var fabric = fabric || { version: '2.4.6' };
function resizeCanvasIfNeeded(t) {
  var e = t.targetCanvas,
    i = e.width,
    r = e.height,
    n = t.destinationWidth,
    s = t.destinationHeight;
  (i === n && r === s) || ((e.width = n), (e.height = s));
}
function copyGLTo2DDrawImage(t, e) {
  var i = t.canvas,
    r = e.targetCanvas,
    n = r.getContext('2d');
  n.translate(0, r.height), n.scale(1, -1);
  var s = i.height - r.height;
  n.drawImage(i, 0, s, r.width, r.height, 0, 0, r.width, r.height);
}
function copyGLTo2DPutImageData(t, e) {
  var i = e.targetCanvas.getContext('2d'),
    r = e.destinationWidth,
    n = e.destinationHeight,
    s = r * n * 4,
    o = new Uint8Array(this.imageBuffer, 0, s),
    a = new Uint8ClampedArray(this.imageBuffer, 0, s);
  t.readPixels(0, 0, r, n, t.RGBA, t.UNSIGNED_BYTE, o);
  var h = new ImageData(a, r, n);
  i.putImageData(h, 0, 0);
}
'undefined' != typeof exports
  ? (exports.fabric = fabric)
  : 'function' == typeof define &&
    define.amd &&
    define([], function() {
      return fabric;
    }),
  'undefined' != typeof document && 'undefined' != typeof window
    ? ((fabric.document = document), (fabric.window = window))
    : ((fabric.document = require('jsdom').jsdom(
        decodeURIComponent(
          '%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E'
        ),
        { features: { FetchExternalResources: ['img'] } }
      )),
      (fabric.jsdomImplForWrapper = require('jsdom/lib/jsdom/living/generated/utils').implForWrapper),
      (fabric.nodeCanvas = require('jsdom/lib/jsdom/utils').Canvas),
      (fabric.window = fabric.document.defaultView),
      (DOMParser = require('xmldom').DOMParser)),
  (fabric.isTouchSupported =
    'ontouchstart' in fabric.window ||
    'ontouchstart' in fabric.document ||
    (fabric.window &&
      fabric.window.navigator &&
      0 < fabric.window.navigator.maxTouchPoints)),
  (fabric.isLikelyNode =
    'undefined' != typeof Buffer && 'undefined' == typeof window),
  (fabric.SHARED_ATTRIBUTES = [
    'display',
    'transform',
    'fill',
    'fill-opacity',
    'fill-rule',
    'opacity',
    'stroke',
    'stroke-dasharray',
    'stroke-linecap',
    'stroke-dashoffset',
    'stroke-linejoin',
    'stroke-miterlimit',
    'stroke-opacity',
    'stroke-width',
    'id',
    'paint-order',
    'instantiated_by_use',
    'clip-path',
  ]),
  (fabric.DPI = 96),
  (fabric.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)'),
  (fabric.fontPaths = {}),
  (fabric.iMatrix = [1, 0, 0, 1, 0, 0]),
  (fabric.canvasModule = 'canvas'),
  (fabric.perfLimitSizeTotal = 2097152),
  (fabric.maxCacheSideLimit = 4096),
  (fabric.minCacheSideLimit = 256),
  (fabric.charWidthsCache = {}),
  (fabric.textureSize = 2048),
  (fabric.enableGLFiltering = !0),
  (fabric.devicePixelRatio =
    fabric.window.devicePixelRatio ||
    fabric.window.webkitDevicePixelRatio ||
    fabric.window.mozDevicePixelRatio ||
    1),
  (fabric.browserShadowBlurConstant = 1),
  (fabric.arcToSegmentsCache = {}),
  (fabric.boundsOfCurveCache = {}),
  (fabric.cachesBoundsOfCurve = !0),
  (fabric.initFilterBackend = function() {
    return fabric.enableGLFiltering &&
      fabric.isWebglSupported &&
      fabric.isWebglSupported(fabric.textureSize)
      ? (console.log('max texture size: ' + fabric.maxTextureSize),
        new fabric.WebglFilterBackend({ tileSize: fabric.textureSize }))
      : fabric.Canvas2dFilterBackend
      ? new fabric.Canvas2dFilterBackend()
      : void 0;
  }),
  'undefined' != typeof document &&
    'undefined' != typeof window &&
    (window.fabric = fabric),
  (function() {
    function r(t, e) {
      if (this.__eventListeners[t]) {
        var i = this.__eventListeners[t];
        e ? (i[i.indexOf(e)] = !1) : fabric.util.array.fill(i, !1);
      }
    }
    function t(t, e) {
      if (
        (this.__eventListeners || (this.__eventListeners = {}),
        1 === arguments.length)
      )
        for (var i in t) this.on(i, t[i]);
      else
        this.__eventListeners[t] || (this.__eventListeners[t] = []),
          this.__eventListeners[t].push(e);
      return this;
    }
    function e(t, e) {
      if (this.__eventListeners) {
        if (0 === arguments.length)
          for (t in this.__eventListeners) r.call(this, t);
        else if (1 === arguments.length && 'object' == typeof t)
          for (var i in t) r.call(this, i, t[i]);
        else r.call(this, t, e);
        return this;
      }
    }
    function i(t, e) {
      if (this.__eventListeners) {
        var i = this.__eventListeners[t];
        if (i) {
          for (var r = 0, n = i.length; r < n; r++)
            i[r] && i[r].call(this, e || {});
          return (
            (this.__eventListeners[t] = i.filter(function(t) {
              return !1 !== t;
            })),
            this
          );
        }
      }
    }
    fabric.Observable = {
      observe: t,
      stopObserving: e,
      fire: i,
      on: t,
      off: e,
      trigger: i,
    };
  })(),
  (fabric.Collection = {
    _objects: [],
    add: function() {
      if (
        (this._objects.push.apply(this._objects, arguments),
        this._onObjectAdded)
      )
        for (var t = 0, e = arguments.length; t < e; t++)
          this._onObjectAdded(arguments[t]);
      return this.renderOnAddRemove && this.requestRenderAll(), this;
    },
    insertAt: function(t, e, i) {
      var r = this._objects;
      return (
        i ? (r[e] = t) : r.splice(e, 0, t),
        this._onObjectAdded && this._onObjectAdded(t),
        this.renderOnAddRemove && this.requestRenderAll(),
        this
      );
    },
    remove: function() {
      for (
        var t, e = this._objects, i = !1, r = 0, n = arguments.length;
        r < n;
        r++
      )
        -1 !== (t = e.indexOf(arguments[r])) &&
          ((i = !0),
          e.splice(t, 1),
          this._onObjectRemoved && this._onObjectRemoved(arguments[r]));
      return this.renderOnAddRemove && i && this.requestRenderAll(), this;
    },
    forEachObject: function(t, e) {
      for (var i = this.getObjects(), r = 0, n = i.length; r < n; r++)
        t.call(e, i[r], r, i);
      return this;
    },
    getObjects: function(e) {
      return void 0 === e
        ? this._objects.concat()
        : this._objects.filter(function(t) {
            return t.type === e;
          });
    },
    item: function(t) {
      return this._objects[t];
    },
    isEmpty: function() {
      return 0 === this._objects.length;
    },
    size: function() {
      return this._objects.length;
    },
    contains: function(t) {
      return -1 < this._objects.indexOf(t);
    },
    complexity: function() {
      return this._objects.reduce(function(t, e) {
        return (t += e.complexity ? e.complexity() : 0);
      }, 0);
    },
  }),
  (fabric.CommonMethods = {
    _setOptions: function(t) {
      for (var e in t) this.set(e, t[e]);
    },
    _initGradient: function(t, e) {
      !t ||
        !t.colorStops ||
        t instanceof fabric.Gradient ||
        this.set(e, new fabric.Gradient(t));
    },
    _initPattern: function(t, e, i) {
      !t || !t.source || t instanceof fabric.Pattern
        ? i && i()
        : this.set(e, new fabric.Pattern(t, i));
    },
    _initClipping: function(t) {
      if (t.clipTo && 'string' == typeof t.clipTo) {
        var e = fabric.util.getFunctionBody(t.clipTo);
        void 0 !== e && (this.clipTo = new Function('ctx', e));
      }
    },
    _setObject: function(t) {
      for (var e in t) this._set(e, t[e]);
    },
    set: function(t, e) {
      return (
        'object' == typeof t
          ? this._setObject(t)
          : 'function' == typeof e && 'clipTo' !== t
          ? this._set(t, e(this.get(t)))
          : this._set(t, e),
        this
      );
    },
    _set: function(t, e) {
      this[t] = e;
    },
    toggle: function(t) {
      var e = this.get(t);
      return 'boolean' == typeof e && this.set(t, !e), this;
    },
    get: function(t) {
      return this[t];
    },
  }),
  (function(s) {
    var d = Math.sqrt,
      g = Math.atan2,
      o = Math.pow,
      a = Math.abs,
      h = Math.PI / 180,
      i = Math.PI / 2;
    fabric.util = {
      cos: function(t) {
        if (0 === t) return 1;
        switch ((t < 0 && (t = -t), t / i)) {
          case 1:
          case 3:
            return 0;
          case 2:
            return -1;
        }
        return Math.cos(t);
      },
      sin: function(t) {
        if (0 === t) return 0;
        var e = 1;
        switch ((t < 0 && (e = -1), t / i)) {
          case 1:
            return e;
          case 2:
            return 0;
          case 3:
            return -e;
        }
        return Math.sin(t);
      },
      removeFromArray: function(t, e) {
        var i = t.indexOf(e);
        return -1 !== i && t.splice(i, 1), t;
      },
      getRandomInt: function(t, e) {
        return Math.floor(Math.random() * (e - t + 1)) + t;
      },
      degreesToRadians: function(t) {
        return t * h;
      },
      radiansToDegrees: function(t) {
        return t / h;
      },
      rotatePoint: function(t, e, i) {
        t.subtractEquals(e);
        var r = fabric.util.rotateVector(t, i);
        return new fabric.Point(r.x, r.y).addEquals(e);
      },
      rotateVector: function(t, e) {
        var i = fabric.util.sin(e),
          r = fabric.util.cos(e);
        return { x: t.x * r - t.y * i, y: t.x * i + t.y * r };
      },
      transformPoint: function(t, e, i) {
        return i
          ? new fabric.Point(e[0] * t.x + e[2] * t.y, e[1] * t.x + e[3] * t.y)
          : new fabric.Point(
              e[0] * t.x + e[2] * t.y + e[4],
              e[1] * t.x + e[3] * t.y + e[5]
            );
      },
      makeBoundingBoxFromPoints: function(t) {
        var e = [t[0].x, t[1].x, t[2].x, t[3].x],
          i = fabric.util.array.min(e),
          r = fabric.util.array.max(e) - i,
          n = [t[0].y, t[1].y, t[2].y, t[3].y],
          s = fabric.util.array.min(n);
        return {
          left: i,
          top: s,
          width: r,
          height: fabric.util.array.max(n) - s,
        };
      },
      invertTransform: function(t) {
        var e = 1 / (t[0] * t[3] - t[1] * t[2]),
          i = [e * t[3], -e * t[1], -e * t[2], e * t[0]],
          r = fabric.util.transformPoint({ x: t[4], y: t[5] }, i, !0);
        return (i[4] = -r.x), (i[5] = -r.y), i;
      },
      toFixed: function(t, e) {
        return parseFloat(Number(t).toFixed(e));
      },
      parseUnit: function(t, e) {
        var i = /\D{0,2}$/.exec(t),
          r = parseFloat(t);
        switch ((e || (e = fabric.Text.DEFAULT_SVG_FONT_SIZE), i[0])) {
          case 'mm':
            return (r * fabric.DPI) / 25.4;
          case 'cm':
            return (r * fabric.DPI) / 2.54;
          case 'in':
            return r * fabric.DPI;
          case 'pt':
            return (r * fabric.DPI) / 72;
          case 'pc':
            return ((r * fabric.DPI) / 72) * 12;
          case 'em':
            return r * e;
          default:
            return r;
        }
      },
      falseFunction: function() {
        return !1;
      },
      getKlass: function(t, e) {
        return (
          (t = fabric.util.string.camelize(
            t.charAt(0).toUpperCase() + t.slice(1)
          )),
          fabric.util.resolveNamespace(e)[t]
        );
      },
      getSvgAttributes: function(t) {
        var e = ['instantiated_by_use', 'style', 'id', 'class'];
        switch (t) {
          case 'linearGradient':
            e = e.concat([
              'x1',
              'y1',
              'x2',
              'y2',
              'gradientUnits',
              'gradientTransform',
            ]);
            break;
          case 'radialGradient':
            e = e.concat([
              'gradientUnits',
              'gradientTransform',
              'cx',
              'cy',
              'r',
              'fx',
              'fy',
              'fr',
            ]);
            break;
          case 'stop':
            e = e.concat(['offset', 'stop-color', 'stop-opacity']);
        }
        return e;
      },
      resolveNamespace: function(t) {
        if (!t) return fabric;
        var e,
          i = t.split('.'),
          r = i.length,
          n = s || fabric.window;
        for (e = 0; e < r; ++e) n = n[i[e]];
        return n;
      },
      loadImage: function(t, e, i, r) {
        if (t) {
          var n = fabric.util.createImage(),
            s = function() {
              e && e.call(i, n), (n = n.onload = n.onerror = null);
            };
          (n.onload = s),
            (n.onerror = function() {
              fabric.log('Error loading ' + n.src),
                e && e.call(i, null, !0),
                (n = n.onload = n.onerror = null);
            }),
            0 !== t.indexOf('data') && r && (n.crossOrigin = r),
            'data:image/svg' === t.substring(0, 14) &&
              ((n.onload = null), fabric.util.loadImageInDom(n, s)),
            (n.src = t);
        } else e && e.call(i, t);
      },
      loadImageInDom: function(t, e) {
        var i = fabric.document.createElement('div');
        (i.style.width = i.style.height = '1px'),
          (i.style.left = i.style.top = '-100%'),
          (i.style.position = 'absolute'),
          i.appendChild(t),
          fabric.document.querySelector('body').appendChild(i),
          (t.onload = function() {
            e(), i.parentNode.removeChild(i), (i = null);
          });
      },
      enlivenObjects: function(t, e, n, s) {
        function o() {
          ++i === r && e && e(a);
        }
        var a = [],
          i = 0,
          r = (t = t || []).length;
        r
          ? t.forEach(function(i, r) {
              i && i.type
                ? fabric.util.getKlass(i.type, n).fromObject(i, function(t, e) {
                    e || (a[r] = t), s && s(i, t, e), o();
                  })
                : o();
            })
          : e && e(a);
      },
      enlivenPatterns: function(t, e) {
        function i() {
          ++n === s && e && e(r);
        }
        var r = [],
          n = 0,
          s = (t = t || []).length;
        s
          ? t.forEach(function(t, e) {
              t && t.source
                ? new fabric.Pattern(t, function(t) {
                    (r[e] = t), i();
                  })
                : ((r[e] = t), i());
            })
          : e && e(r);
      },
      groupSVGElements: function(t, e, i) {
        var r;
        return t && 1 === t.length
          ? t[0]
          : (e &&
              (e.width && e.height
                ? (e.centerPoint = { x: e.width / 2, y: e.height / 2 })
                : (delete e.width, delete e.height)),
            (r = new fabric.Group(t, e)),
            void 0 !== i && (r.sourcePath = i),
            r);
      },
      populateWithProperties: function(t, e, i) {
        if (i && '[object Array]' === Object.prototype.toString.call(i))
          for (var r = 0, n = i.length; r < n; r++)
            i[r] in t && (e[i[r]] = t[i[r]]);
      },
      drawDashedLine: function(t, e, i, r, n, s) {
        var o = r - e,
          a = n - i,
          h = d(o * o + a * a),
          c = g(a, o),
          l = s.length,
          u = 0,
          f = !0;
        for (
          t.save(), t.translate(e, i), t.moveTo(0, 0), t.rotate(c), e = 0;
          e < h;

        )
          h < (e += s[u++ % l]) && (e = h),
            t[f ? 'lineTo' : 'moveTo'](e, 0),
            (f = !f);
        t.restore();
      },
      createCanvasElement: function() {
        return fabric.document.createElement('canvas');
      },
      copyCanvasElement: function(t) {
        var e = fabric.util.createCanvasElement();
        return (
          (e.width = t.width),
          (e.height = t.height),
          e.getContext('2d').drawImage(t, 0, 0),
          e
        );
      },
      createImage: function() {
        return fabric.document.createElement('img');
      },
      clipContext: function(t, e) {
        e.save(), e.beginPath(), t.clipTo(e), e.clip();
      },
      multiplyTransformMatrices: function(t, e, i) {
        return [
          t[0] * e[0] + t[2] * e[1],
          t[1] * e[0] + t[3] * e[1],
          t[0] * e[2] + t[2] * e[3],
          t[1] * e[2] + t[3] * e[3],
          i ? 0 : t[0] * e[4] + t[2] * e[5] + t[4],
          i ? 0 : t[1] * e[4] + t[3] * e[5] + t[5],
        ];
      },
      qrDecompose: function(t) {
        var e = g(t[1], t[0]),
          i = o(t[0], 2) + o(t[1], 2),
          r = d(i),
          n = (t[0] * t[3] - t[2] * t[1]) / r,
          s = g(t[0] * t[2] + t[1] * t[3], i);
        return {
          angle: e / h,
          scaleX: r,
          scaleY: n,
          skewX: s / h,
          skewY: 0,
          translateX: t[4],
          translateY: t[5],
        };
      },
      customTransformMatrix: function(t, e, i) {
        var r = [1, 0, a(Math.tan(i * h)), 1],
          n = [a(t), 0, 0, a(e)];
        return fabric.util.multiplyTransformMatrices(n, r, !0);
      },
      resetObjectTransform: function(t) {
        (t.scaleX = 1),
          (t.scaleY = 1),
          (t.skewX = 0),
          (t.skewY = 0),
          (t.flipX = !1),
          (t.flipY = !1),
          t.rotate(0);
      },
      saveObjectTransform: function(t) {
        return {
          scaleX: t.scaleX,
          scaleY: t.scaleY,
          skewX: t.skewX,
          skewY: t.skewY,
          angle: t.angle,
          left: t.left,
          flipX: t.flipX,
          flipY: t.flipY,
          top: t.top,
        };
      },
      getFunctionBody: function(t) {
        return (String(t).match(/function[^{]*\{([\s\S]*)\}/) || {})[1];
      },
      isTransparent: function(t, e, i, r) {
        0 < r && (r < e ? (e -= r) : (e = 0), r < i ? (i -= r) : (i = 0));
        var n,
          s = !0,
          o = t.getImageData(e, i, 2 * r || 1, 2 * r || 1),
          a = o.data.length;
        for (n = 3; n < a && !1 !== (s = o.data[n] <= 0); n += 4);
        return (o = null), s;
      },
      parsePreserveAspectRatioAttribute: function(t) {
        var e,
          i = 'meet',
          r = t.split(' ');
        return (
          r &&
            r.length &&
            ('meet' !== (i = r.pop()) && 'slice' !== i
              ? ((e = i), (i = 'meet'))
              : r.length && (e = r.pop())),
          {
            meetOrSlice: i,
            alignX: 'none' !== e ? e.slice(1, 4) : 'none',
            alignY: 'none' !== e ? e.slice(5, 8) : 'none',
          }
        );
      },
      clearFabricFontCache: function(t) {
        (t = (t || '').toLowerCase())
          ? fabric.charWidthsCache[t] && delete fabric.charWidthsCache[t]
          : (fabric.charWidthsCache = {});
      },
      limitDimsByArea: function(t, e) {
        var i = Math.sqrt(e * t),
          r = Math.floor(e / i);
        return { x: Math.floor(i), y: r };
      },
      capValue: function(t, e, i) {
        return Math.max(t, Math.min(e, i));
      },
      findScaleToFit: function(t, e) {
        return Math.min(e.width / t.width, e.height / t.height);
      },
      findScaleToCover: function(t, e) {
        return Math.max(e.width / t.width, e.height / t.height);
      },
    };
  })('undefined' != typeof exports ? exports : this),
  (function() {
    var Q = Array.prototype.join;
    function v(t, e, i, r, n, s, o) {
      var a = Q.call(arguments);
      if (fabric.arcToSegmentsCache[a]) return fabric.arcToSegmentsCache[a];
      var h = Math.PI,
        c = (o * h) / 180,
        l = fabric.util.sin(c),
        u = fabric.util.cos(c),
        f = 0,
        d = 0,
        g = -u * t * 0.5 - l * e * 0.5,
        p = -u * e * 0.5 + l * t * 0.5,
        v = (i = Math.abs(i)) * i,
        m = (r = Math.abs(r)) * r,
        b = p * p,
        _ = g * g,
        y = v * m - v * b - m * _,
        x = 0;
      if (y < 0) {
        var C = Math.sqrt(1 - y / (v * m));
        (i *= C), (r *= C);
      } else x = (n === s ? -1 : 1) * Math.sqrt(y / (v * b + m * _));
      var S = (x * i * p) / r,
        T = (-x * r * g) / i,
        w = u * S - l * T + 0.5 * t,
        O = l * S + u * T + 0.5 * e,
        k = Z(1, 0, (g - S) / i, (p - T) / r),
        D = Z((g - S) / i, (p - T) / r, (-g - S) / i, (-p - T) / r);
      0 === s && 0 < D ? (D -= 2 * h) : 1 === s && D < 0 && (D += 2 * h);
      for (
        var E,
          P,
          j,
          A,
          M,
          F,
          I,
          L,
          R,
          B,
          X,
          W,
          Y,
          U,
          z,
          N,
          G,
          V = Math.ceil(Math.abs((D / h) * 2)),
          H = [],
          q = D / V,
          K = ((8 / 3) * Math.sin(q / 4) * Math.sin(q / 4)) / Math.sin(q / 2),
          J = k + q,
          $ = 0;
        $ < V;
        $++
      )
        (H[$] = ((E = k),
        (P = J),
        (j = u),
        (A = l),
        (M = i),
        (F = r),
        (I = w),
        (L = O),
        (R = K),
        (B = f),
        (X = d),
        void 0,
        (W = fabric.util.cos(E)),
        (Y = fabric.util.sin(E)),
        (U = fabric.util.cos(P)),
        (z = fabric.util.sin(P)),
        [
          B + R * (-j * M * Y - A * F * W),
          X + R * (-A * M * Y + j * F * W),
          (N = j * M * U - A * F * z + I) + R * (j * M * z + A * F * U),
          (G = A * M * U + j * F * z + L) + R * (A * M * z - j * F * U),
          N,
          G,
        ])),
          (f = H[$][4]),
          (d = H[$][5]),
          (k = J),
          (J += q);
      return (fabric.arcToSegmentsCache[a] = H);
    }
    function Z(t, e, i, r) {
      var n = Math.atan2(e, t),
        s = Math.atan2(r, i);
      return n <= s ? s - n : 2 * Math.PI - (n - s);
    }
    function m(t, e, i, r, n, s, o, a) {
      var h;
      if (
        fabric.cachesBoundsOfCurve &&
        ((h = Q.call(arguments)), fabric.boundsOfCurveCache[h])
      )
        return fabric.boundsOfCurveCache[h];
      var c,
        l,
        u,
        f,
        d,
        g,
        p,
        v,
        m = Math.sqrt,
        b = Math.min,
        _ = Math.max,
        y = Math.abs,
        x = [],
        C = [[], []];
      (l = 6 * t - 12 * i + 6 * n),
        (c = -3 * t + 9 * i - 9 * n + 3 * o),
        (u = 3 * i - 3 * t);
      for (var S = 0; S < 2; ++S)
        if (
          (0 < S &&
            ((l = 6 * e - 12 * r + 6 * s),
            (c = -3 * e + 9 * r - 9 * s + 3 * a),
            (u = 3 * r - 3 * e)),
          y(c) < 1e-12)
        ) {
          if (y(l) < 1e-12) continue;
          0 < (f = -u / l) && f < 1 && x.push(f);
        } else
          (p = l * l - 4 * u * c) < 0 ||
            (0 < (d = (-l + (v = m(p))) / (2 * c)) && d < 1 && x.push(d),
            0 < (g = (-l - v) / (2 * c)) && g < 1 && x.push(g));
      for (var T, w, O, k = x.length, D = k; k--; )
        (T =
          (O = 1 - (f = x[k])) * O * O * t +
          3 * O * O * f * i +
          3 * O * f * f * n +
          f * f * f * o),
          (C[0][k] = T),
          (w =
            O * O * O * e +
            3 * O * O * f * r +
            3 * O * f * f * s +
            f * f * f * a),
          (C[1][k] = w);
      (C[0][D] = t), (C[1][D] = e), (C[0][D + 1] = o), (C[1][D + 1] = a);
      var E = [
        { x: b.apply(null, C[0]), y: b.apply(null, C[1]) },
        { x: _.apply(null, C[0]), y: _.apply(null, C[1]) },
      ];
      return (
        fabric.cachesBoundsOfCurve && (fabric.boundsOfCurveCache[h] = E), E
      );
    }
    (fabric.util.drawArc = function(t, e, i, r) {
      for (
        var n = r[0],
          s = r[1],
          o = r[2],
          a = r[3],
          h = r[4],
          c = [[], [], [], []],
          l = v(r[5] - e, r[6] - i, n, s, a, h, o),
          u = 0,
          f = l.length;
        u < f;
        u++
      )
        (c[u][0] = l[u][0] + e),
          (c[u][1] = l[u][1] + i),
          (c[u][2] = l[u][2] + e),
          (c[u][3] = l[u][3] + i),
          (c[u][4] = l[u][4] + e),
          (c[u][5] = l[u][5] + i),
          t.bezierCurveTo.apply(t, c[u]);
    }),
      (fabric.util.getBoundsOfArc = function(t, e, i, r, n, s, o, a, h) {
        for (
          var c,
            l = 0,
            u = 0,
            f = [],
            d = v(a - t, h - e, i, r, s, o, n),
            g = 0,
            p = d.length;
          g < p;
          g++
        )
          (c = m(l, u, d[g][0], d[g][1], d[g][2], d[g][3], d[g][4], d[g][5])),
            f.push({ x: c[0].x + t, y: c[0].y + e }),
            f.push({ x: c[1].x + t, y: c[1].y + e }),
            (l = d[g][4]),
            (u = d[g][5]);
        return f;
      }),
      (fabric.util.getBoundsOfCurve = m);
  })(),
  (function() {
    var o = Array.prototype.slice;
    function i(t, e, i) {
      if (t && 0 !== t.length) {
        var r = t.length - 1,
          n = e ? t[r][e] : t[r];
        if (e) for (; r--; ) i(t[r][e], n) && (n = t[r][e]);
        else for (; r--; ) i(t[r], n) && (n = t[r]);
        return n;
      }
    }
    fabric.util.array = {
      fill: function(t, e) {
        for (var i = t.length; i--; ) t[i] = e;
        return t;
      },
      invoke: function(t, e) {
        for (
          var i = o.call(arguments, 2), r = [], n = 0, s = t.length;
          n < s;
          n++
        )
          r[n] = i.length ? t[n][e].apply(t[n], i) : t[n][e].call(t[n]);
        return r;
      },
      min: function(t, e) {
        return i(t, e, function(t, e) {
          return t < e;
        });
      },
      max: function(t, e) {
        return i(t, e, function(t, e) {
          return e <= t;
        });
      },
    };
  })(),
  (function() {
    function o(t, e, i) {
      if (i)
        if (!fabric.isLikelyNode && e instanceof Element) t = e;
        else if (e instanceof Array) {
          t = [];
          for (var r = 0, n = e.length; r < n; r++) t[r] = o({}, e[r], i);
        } else if (e && 'object' == typeof e)
          for (var s in e)
            'canvas' === s
              ? (t[s] = o({}, e[s]))
              : e.hasOwnProperty(s) && (t[s] = o({}, e[s], i));
        else t = e;
      else for (var s in e) t[s] = e[s];
      return t;
    }
    (fabric.util.object = {
      extend: o,
      clone: function(t, e) {
        return o({}, t, e);
      },
    }),
      fabric.util.object.extend(fabric.util, fabric.Observable);
  })(),
  (function() {
    function n(t, e) {
      var i = t.charCodeAt(e);
      if (isNaN(i)) return '';
      if (i < 55296 || 57343 < i) return t.charAt(e);
      if (55296 <= i && i <= 56319) {
        if (t.length <= e + 1)
          throw 'High surrogate without following low surrogate';
        var r = t.charCodeAt(e + 1);
        if (r < 56320 || 57343 < r)
          throw 'High surrogate without following low surrogate';
        return t.charAt(e) + t.charAt(e + 1);
      }
      if (0 === e) throw 'Low surrogate without preceding high surrogate';
      var n = t.charCodeAt(e - 1);
      if (n < 55296 || 56319 < n)
        throw 'Low surrogate without preceding high surrogate';
      return !1;
    }
    fabric.util.string = {
      camelize: function(t) {
        return t.replace(/-+(.)?/g, function(t, e) {
          return e ? e.toUpperCase() : '';
        });
      },
      capitalize: function(t, e) {
        return (
          t.charAt(0).toUpperCase() +
          (e ? t.slice(1) : t.slice(1).toLowerCase())
        );
      },
      escapeXml: function(t) {
        return t
          .replace(/&/g, '&amp;')
          .replace(/"/g, '&quot;')
          .replace(/'/g, '&apos;')
          .replace(/</g, '&lt;')
          .replace(/>/g, '&gt;');
      },
      graphemeSplit: function(t) {
        var e,
          i = 0,
          r = [];
        for (i = 0; i < t.length; i++) !1 !== (e = n(t, i)) && r.push(e);
        return r;
      },
    };
  })(),
  (function() {
    var s = Array.prototype.slice,
      o = function() {},
      i = (function() {
        for (var t in { toString: 1 }) if ('toString' === t) return !1;
        return !0;
      })(),
      a = function(t, r, n) {
        for (var e in r)
          e in t.prototype &&
          'function' == typeof t.prototype[e] &&
          -1 < (r[e] + '').indexOf('callSuper')
            ? (t.prototype[e] = (function(i) {
                return function() {
                  var t = this.constructor.superclass;
                  this.constructor.superclass = n;
                  var e = r[i].apply(this, arguments);
                  if (((this.constructor.superclass = t), 'initialize' !== i))
                    return e;
                };
              })(e))
            : (t.prototype[e] = r[e]),
            i &&
              (r.toString !== Object.prototype.toString &&
                (t.prototype.toString = r.toString),
              r.valueOf !== Object.prototype.valueOf &&
                (t.prototype.valueOf = r.valueOf));
      };
    function h() {}
    function c(t) {
      for (var e = null, i = this; i.constructor.superclass; ) {
        var r = i.constructor.superclass.prototype[t];
        if (i[t] !== r) {
          e = r;
          break;
        }
        i = i.constructor.superclass.prototype;
      }
      return e
        ? 1 < arguments.length
          ? e.apply(this, s.call(arguments, 1))
          : e.call(this)
        : console.log(
            'tried to callSuper ' + t + ', method not found in prototype chain',
            this
          );
    }
    fabric.util.createClass = function() {
      var t = null,
        e = s.call(arguments, 0);
      function i() {
        this.initialize.apply(this, arguments);
      }
      'function' == typeof e[0] && (t = e.shift()),
        (i.superclass = t),
        (i.subclasses = []),
        t &&
          ((h.prototype = t.prototype),
          (i.prototype = new h()),
          t.subclasses.push(i));
      for (var r = 0, n = e.length; r < n; r++) a(i, e[r], t);
      return (
        i.prototype.initialize || (i.prototype.initialize = o),
        ((i.prototype.constructor = i).prototype.callSuper = c),
        i
      );
    };
  })(),
  (function() {
    function t(t) {
      var e,
        i,
        r = Array.prototype.slice.call(arguments, 1),
        n = r.length;
      for (i = 0; i < n; i++)
        if (((e = typeof t[r[i]]), !/^(?:function|object|unknown)$/.test(e)))
          return !1;
      return !0;
    }
    var n,
      s,
      e,
      i,
      a = ((e = 0),
      function(t) {
        return t.__uniqueID || (t.__uniqueID = 'uniqueID__' + e++);
      });
    function o(t, e) {
      return {
        handler: e,
        wrappedHandler: ((i = t),
        (r = e),
        function(t) {
          r.call(n(i), t || fabric.window.event);
        }),
      };
      var i, r;
    }
    (i = {}),
      (n = function(t) {
        return i[t];
      }),
      (s = function(t, e) {
        i[t] = e;
      });
    var r,
      h,
      c =
        t(
          fabric.document.documentElement,
          'addEventListener',
          'removeEventListener'
        ) && t(fabric.window, 'addEventListener', 'removeEventListener'),
      l =
        t(fabric.document.documentElement, 'attachEvent', 'detachEvent') &&
        t(fabric.window, 'attachEvent', 'detachEvent'),
      u = {},
      f = {};
    c
      ? ((r = function(t, e, i, r) {
          t && t.addEventListener(e, i, !l && r);
        }),
        (h = function(t, e, i, r) {
          t && t.removeEventListener(e, i, !l && r);
        }))
      : l
      ? ((r = function(t, e, i) {
          if (t) {
            var r = a(t);
            s(r, t), u[r] || (u[r] = {}), u[r][e] || (u[r][e] = []);
            var n = o(r, i);
            u[r][e].push(n), t.attachEvent('on' + e, n.wrappedHandler);
          }
        }),
        (h = function(t, e, i) {
          if (t) {
            var r,
              n = a(t);
            if (u[n] && u[n][e])
              for (var s = 0, o = u[n][e].length; s < o; s++)
                (r = u[n][e][s]) &&
                  r.handler === i &&
                  (t.detachEvent('on' + e, r.wrappedHandler),
                  (u[n][e][s] = null));
          }
        }))
      : ((r = function(t, e, i) {
          if (t) {
            var n,
              s,
              r = a(t);
            if ((f[r] || (f[r] = {}), !f[r][e])) {
              f[r][e] = [];
              var o = t['on' + e];
              o && f[r][e].push(o),
                (t['on' + e] = ((n = r),
                (s = e),
                function(t) {
                  if (f[n] && f[n][s])
                    for (var e = f[n][s], i = 0, r = e.length; i < r; i++)
                      e[i].call(this, t || fabric.window.event);
                }));
            }
            f[r][e].push(i);
          }
        }),
        (h = function(t, e, i) {
          if (t) {
            var r = a(t);
            if (f[r] && f[r][e])
              for (var n = f[r][e], s = 0, o = n.length; s < o; s++)
                n[s] === i && n.splice(s, 1);
          }
        })),
      (fabric.util.addListener = r),
      (fabric.util.removeListener = h);
    var d = function(t) {
        return t.clientX;
      },
      g = function(t) {
        return t.clientY;
      };
    function p(t, e, i) {
      var r,
        n = t['touchend' === t.type ? 'changedTouches' : 'touches'];
      return n && n[0] && (r = n[0][i]), void 0 === r && (r = t[i]), r;
    }
    fabric.isTouchSupported &&
      ((d = function(t) {
        return p(t, 0, 'clientX');
      }),
      (g = function(t) {
        return p(t, 0, 'clientY');
      })),
      (fabric.util.getPointer = function(t) {
        t || (t = fabric.window.event);
        var e =
            t.target ||
            ('unknown' != typeof t.srcElement ? t.srcElement : null),
          i = fabric.util.getScrollLeftTop(e);
        return { x: d(t) + i.left, y: g(t) + i.top };
      });
  })(),
  (function() {
    var t = fabric.document.createElement('div'),
      e = 'string' == typeof t.style.opacity,
      i = 'string' == typeof t.style.filter,
      r = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,
      n = function(t) {
        return t;
      };
    e
      ? (n = function(t, e) {
          return (t.style.opacity = e), t;
        })
      : i &&
        (n = function(t, e) {
          var i = t.style;
          return (
            t.currentStyle && !t.currentStyle.hasLayout && (i.zoom = 1),
            r.test(i.filter)
              ? ((e = 0.9999 <= e ? '' : 'alpha(opacity=' + 100 * e + ')'),
                (i.filter = i.filter.replace(r, e)))
              : (i.filter += ' alpha(opacity=' + 100 * e + ')'),
            t
          );
        }),
      (fabric.util.setStyle = function(t, e) {
        var i = t.style;
        if (!i) return t;
        if ('string' == typeof e)
          return (
            (t.style.cssText += ';' + e),
            -1 < e.indexOf('opacity')
              ? n(t, e.match(/opacity:\s*(\d?\.?\d*)/)[1])
              : t
          );
        for (var r in e)
          'opacity' === r
            ? n(t, e[r])
            : (i[
                'float' === r || 'cssFloat' === r
                  ? void 0 === i.styleFloat
                    ? 'cssFloat'
                    : 'styleFloat'
                  : r
              ] = e[r]);
        return t;
      });
  })(),
  (function() {
    var e = Array.prototype.slice;
    var t,
      h,
      i,
      r,
      n = function(t) {
        return e.call(t, 0);
      };
    try {
      t = n(fabric.document.childNodes) instanceof Array;
    } catch (t) {}
    function s(t, e) {
      var i = fabric.document.createElement(t);
      for (var r in e)
        'class' === r
          ? (i.className = e[r])
          : 'for' === r
          ? (i.htmlFor = e[r])
          : i.setAttribute(r, e[r]);
      return i;
    }
    function c(t) {
      for (
        var e = 0,
          i = 0,
          r = fabric.document.documentElement,
          n = fabric.document.body || { scrollLeft: 0, scrollTop: 0 };
        t &&
        (t.parentNode || t.host) &&
        ((t = t.parentNode || t.host) === fabric.document
          ? ((e = n.scrollLeft || r.scrollLeft || 0),
            (i = n.scrollTop || r.scrollTop || 0))
          : ((e += t.scrollLeft || 0), (i += t.scrollTop || 0)),
        1 !== t.nodeType || 'fixed' !== t.style.position);

      );
      return { left: e, top: i };
    }
    t ||
      (n = function(t) {
        for (var e = new Array(t.length), i = t.length; i--; ) e[i] = t[i];
        return e;
      }),
      (h =
        fabric.document.defaultView &&
        fabric.document.defaultView.getComputedStyle
          ? function(t, e) {
              var i = fabric.document.defaultView.getComputedStyle(t, null);
              return i ? i[e] : void 0;
            }
          : function(t, e) {
              var i = t.style[e];
              return !i && t.currentStyle && (i = t.currentStyle[e]), i;
            }),
      (i = fabric.document.documentElement.style),
      (r =
        'userSelect' in i
          ? 'userSelect'
          : 'MozUserSelect' in i
          ? 'MozUserSelect'
          : 'WebkitUserSelect' in i
          ? 'WebkitUserSelect'
          : 'KhtmlUserSelect' in i
          ? 'KhtmlUserSelect'
          : ''),
      (fabric.util.makeElementUnselectable = function(t) {
        return (
          void 0 !== t.onselectstart &&
            (t.onselectstart = fabric.util.falseFunction),
          r
            ? (t.style[r] = 'none')
            : 'string' == typeof t.unselectable && (t.unselectable = 'on'),
          t
        );
      }),
      (fabric.util.makeElementSelectable = function(t) {
        return (
          void 0 !== t.onselectstart && (t.onselectstart = null),
          r
            ? (t.style[r] = '')
            : 'string' == typeof t.unselectable && (t.unselectable = ''),
          t
        );
      }),
      (fabric.util.getScript = function(t, e) {
        var i = fabric.document.getElementsByTagName('head')[0],
          r = fabric.document.createElement('script'),
          n = !0;
        (r.onload = r.onreadystatechange = function(t) {
          if (n) {
            if (
              'string' == typeof this.readyState &&
              'loaded' !== this.readyState &&
              'complete' !== this.readyState
            )
              return;
            (n = !1),
              e(t || fabric.window.event),
              (r = r.onload = r.onreadystatechange = null);
          }
        }),
          (r.src = t),
          i.appendChild(r);
      }),
      (fabric.util.getById = function(t) {
        return 'string' == typeof t ? fabric.document.getElementById(t) : t;
      }),
      (fabric.util.toArray = n),
      (fabric.util.makeElement = s),
      (fabric.util.addClass = function(t, e) {
        t &&
          -1 === (' ' + t.className + ' ').indexOf(' ' + e + ' ') &&
          (t.className += (t.className ? ' ' : '') + e);
      }),
      (fabric.util.wrapElement = function(t, e, i) {
        return (
          'string' == typeof e && (e = s(e, i)),
          t.parentNode && t.parentNode.replaceChild(e, t),
          e.appendChild(t),
          e
        );
      }),
      (fabric.util.getScrollLeftTop = c),
      (fabric.util.getElementOffset = function(t) {
        var e,
          i,
          r = t && t.ownerDocument,
          n = { left: 0, top: 0 },
          s = { left: 0, top: 0 },
          o = {
            borderLeftWidth: 'left',
            borderTopWidth: 'top',
            paddingLeft: 'left',
            paddingTop: 'top',
          };
        if (!r) return s;
        for (var a in o) s[o[a]] += parseInt(h(t, a), 10) || 0;
        return (
          (e = r.documentElement),
          void 0 !== t.getBoundingClientRect && (n = t.getBoundingClientRect()),
          (i = c(t)),
          {
            left: n.left + i.left - (e.clientLeft || 0) + s.left,
            top: n.top + i.top - (e.clientTop || 0) + s.top,
          }
        );
      }),
      (fabric.util.getElementStyle = h),
      (fabric.util.getNodeCanvas = function(t) {
        var e = fabric.jsdomImplForWrapper(t);
        return e._canvas || e._image;
      }),
      (fabric.util.cleanUpJsdomNode = function(t) {
        if (fabric.isLikelyNode) {
          var e = fabric.jsdomImplForWrapper(t);
          e &&
            ((e._image = null),
            (e._canvas = null),
            (e._currentSrc = null),
            (e._attributes = null),
            (e._classList = null));
        }
      });
  })(),
  (function() {
    function h() {}
    fabric.util.request = function(t, e) {
      e || (e = {});
      var i,
        r,
        n = e.method ? e.method.toUpperCase() : 'GET',
        s = e.onComplete || function() {},
        o = new fabric.window.XMLHttpRequest(),
        a = e.body || e.parameters;
      return (
        (o.onreadystatechange = function() {
          4 === o.readyState && (s(o), (o.onreadystatechange = h));
        }),
        'GET' === n &&
          ((a = null),
          'string' == typeof e.parameters &&
            ((i = t),
            (r = e.parameters),
            (t = i + (/\?/.test(i) ? '&' : '?') + r))),
        o.open(n, t, !0),
        ('POST' !== n && 'PUT' !== n) ||
          o.setRequestHeader(
            'Content-Type',
            'application/x-www-form-urlencoded'
          ),
        o.send(a),
        o
      );
    };
  })(),
  (fabric.log = function() {}),
  (fabric.warn = function() {}),
  'undefined' != typeof console &&
    ['log', 'warn'].forEach(function(t) {
      void 0 !== console[t] &&
        'function' == typeof console[t].apply &&
        (fabric[t] = function() {
          return console[t].apply(console, arguments);
        });
    }),
  (function() {
    function e() {
      return !1;
    }
    var t =
        fabric.window.requestAnimationFrame ||
        fabric.window.webkitRequestAnimationFrame ||
        fabric.window.mozRequestAnimationFrame ||
        fabric.window.oRequestAnimationFrame ||
        fabric.window.msRequestAnimationFrame ||
        function(t) {
          return fabric.window.setTimeout(t, 1e3 / 60);
        },
      i = fabric.window.cancelAnimationFrame || fabric.window.clearTimeout;
    function b() {
      return t.apply(fabric.window, arguments);
    }
    (fabric.util.animate = function(m) {
      b(function(t) {
        m || (m = {});
        var o,
          a = t || +new Date(),
          h = m.duration || 500,
          c = a + h,
          l = m.onChange || e,
          u = m.abort || e,
          f = m.onComplete || e,
          d =
            m.easing ||
            function(t, e, i, r) {
              return -i * Math.cos((t / r) * (Math.PI / 2)) + i + e;
            },
          g = 'startValue' in m ? m.startValue : 0,
          p = 'endValue' in m ? m.endValue : 100,
          v = m.byValue || p - g;
        m.onStart && m.onStart(),
          (function t(e) {
            if (u()) f(p, 1, 1);
            else {
              o = e || +new Date();
              var i = c < o ? h : o - a,
                r = i / h,
                n = d(i, g, v, h),
                s = Math.abs((n - g) / v);
              l(n, s, r), c < o ? m.onComplete && m.onComplete() : b(t);
            }
          })(a);
      });
    }),
      (fabric.util.requestAnimFrame = b),
      (fabric.util.cancelAnimFrame = function() {
        return i.apply(fabric.window, arguments);
      });
  })(),
  (fabric.util.animateColor = function(t, e, i, c) {
    var r = new fabric.Color(t).getSource(),
      n = new fabric.Color(e).getSource();
    (c = c || {}),
      fabric.util.animate(
        fabric.util.object.extend(c, {
          duration: i || 500,
          startValue: r,
          endValue: n,
          byValue: n,
          easing: function(t, e, i, r) {
            var n,
              s,
              o,
              a,
              h = c.colorEasing
                ? c.colorEasing(t, r)
                : 1 - Math.cos((t / r) * (Math.PI / 2));
            return (
              (n = e),
              (s = i),
              (o = h),
              (a =
                'rgba(' +
                parseInt(n[0] + o * (s[0] - n[0]), 10) +
                ',' +
                parseInt(n[1] + o * (s[1] - n[1]), 10) +
                ',' +
                parseInt(n[2] + o * (s[2] - n[2]), 10)),
              (a += ',' + (n && s ? parseFloat(n[3] + o * (s[3] - n[3])) : 1)),
              (a += ')')
            );
          },
        })
      );
  }),
  (function() {
    function o(t, e, i, r) {
      return (
        t < Math.abs(e)
          ? ((t = e), (r = i / 4))
          : (r =
              0 === e && 0 === t
                ? (i / (2 * Math.PI)) * Math.asin(1)
                : (i / (2 * Math.PI)) * Math.asin(e / t)),
        { a: t, c: e, p: i, s: r }
      );
    }
    function a(t, e, i) {
      return (
        t.a *
        Math.pow(2, 10 * (e -= 1)) *
        Math.sin(((e * i - t.s) * (2 * Math.PI)) / t.p)
      );
    }
    function n(t, e, i, r) {
      return i - s(r - t, 0, i, r) + e;
    }
    function s(t, e, i, r) {
      return (t /= r) < 1 / 2.75
        ? i * (7.5625 * t * t) + e
        : t < 2 / 2.75
        ? i * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + e
        : t < 2.5 / 2.75
        ? i * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + e
        : i * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + e;
    }
    fabric.util.ease = {
      easeInQuad: function(t, e, i, r) {
        return i * (t /= r) * t + e;
      },
      easeOutQuad: function(t, e, i, r) {
        return -i * (t /= r) * (t - 2) + e;
      },
      easeInOutQuad: function(t, e, i, r) {
        return (t /= r / 2) < 1
          ? (i / 2) * t * t + e
          : (-i / 2) * (--t * (t - 2) - 1) + e;
      },
      easeInCubic: function(t, e, i, r) {
        return i * (t /= r) * t * t + e;
      },
      easeOutCubic: function(t, e, i, r) {
        return i * ((t = t / r - 1) * t * t + 1) + e;
      },
      easeInOutCubic: function(t, e, i, r) {
        return (t /= r / 2) < 1
          ? (i / 2) * t * t * t + e
          : (i / 2) * ((t -= 2) * t * t + 2) + e;
      },
      easeInQuart: function(t, e, i, r) {
        return i * (t /= r) * t * t * t + e;
      },
      easeOutQuart: function(t, e, i, r) {
        return -i * ((t = t / r - 1) * t * t * t - 1) + e;
      },
      easeInOutQuart: function(t, e, i, r) {
        return (t /= r / 2) < 1
          ? (i / 2) * t * t * t * t + e
          : (-i / 2) * ((t -= 2) * t * t * t - 2) + e;
      },
      easeInQuint: function(t, e, i, r) {
        return i * (t /= r) * t * t * t * t + e;
      },
      easeOutQuint: function(t, e, i, r) {
        return i * ((t = t / r - 1) * t * t * t * t + 1) + e;
      },
      easeInOutQuint: function(t, e, i, r) {
        return (t /= r / 2) < 1
          ? (i / 2) * t * t * t * t * t + e
          : (i / 2) * ((t -= 2) * t * t * t * t + 2) + e;
      },
      easeInSine: function(t, e, i, r) {
        return -i * Math.cos((t / r) * (Math.PI / 2)) + i + e;
      },
      easeOutSine: function(t, e, i, r) {
        return i * Math.sin((t / r) * (Math.PI / 2)) + e;
      },
      easeInOutSine: function(t, e, i, r) {
        return (-i / 2) * (Math.cos((Math.PI * t) / r) - 1) + e;
      },
      easeInExpo: function(t, e, i, r) {
        return 0 === t ? e : i * Math.pow(2, 10 * (t / r - 1)) + e;
      },
      easeOutExpo: function(t, e, i, r) {
        return t === r ? e + i : i * (1 - Math.pow(2, (-10 * t) / r)) + e;
      },
      easeInOutExpo: function(t, e, i, r) {
        return 0 === t
          ? e
          : t === r
          ? e + i
          : (t /= r / 2) < 1
          ? (i / 2) * Math.pow(2, 10 * (t - 1)) + e
          : (i / 2) * (2 - Math.pow(2, -10 * --t)) + e;
      },
      easeInCirc: function(t, e, i, r) {
        return -i * (Math.sqrt(1 - (t /= r) * t) - 1) + e;
      },
      easeOutCirc: function(t, e, i, r) {
        return i * Math.sqrt(1 - (t = t / r - 1) * t) + e;
      },
      easeInOutCirc: function(t, e, i, r) {
        return (t /= r / 2) < 1
          ? (-i / 2) * (Math.sqrt(1 - t * t) - 1) + e
          : (i / 2) * (Math.sqrt(1 - (t -= 2) * t) + 1) + e;
      },
      easeInElastic: function(t, e, i, r) {
        var n = 0;
        return 0 === t
          ? e
          : 1 == (t /= r)
          ? e + i
          : (n || (n = 0.3 * r), -a(o(i, i, n, 1.70158), t, r) + e);
      },
      easeOutElastic: function(t, e, i, r) {
        var n = 0;
        if (0 === t) return e;
        if (1 == (t /= r)) return e + i;
        n || (n = 0.3 * r);
        var s = o(i, i, n, 1.70158);
        return (
          s.a *
            Math.pow(2, -10 * t) *
            Math.sin(((t * r - s.s) * (2 * Math.PI)) / s.p) +
          s.c +
          e
        );
      },
      easeInOutElastic: function(t, e, i, r) {
        var n = 0;
        if (0 === t) return e;
        if (2 == (t /= r / 2)) return e + i;
        n || (n = r * (0.3 * 1.5));
        var s = o(i, i, n, 1.70158);
        return t < 1
          ? -0.5 * a(s, t, r) + e
          : s.a *
              Math.pow(2, -10 * (t -= 1)) *
              Math.sin(((t * r - s.s) * (2 * Math.PI)) / s.p) *
              0.5 +
              s.c +
              e;
      },
      easeInBack: function(t, e, i, r, n) {
        return (
          void 0 === n && (n = 1.70158),
          i * (t /= r) * t * ((n + 1) * t - n) + e
        );
      },
      easeOutBack: function(t, e, i, r, n) {
        return (
          void 0 === n && (n = 1.70158),
          i * ((t = t / r - 1) * t * ((n + 1) * t + n) + 1) + e
        );
      },
      easeInOutBack: function(t, e, i, r, n) {
        return (
          void 0 === n && (n = 1.70158),
          (t /= r / 2) < 1
            ? (i / 2) * (t * t * ((1 + (n *= 1.525)) * t - n)) + e
            : (i / 2) * ((t -= 2) * t * ((1 + (n *= 1.525)) * t + n) + 2) + e
        );
      },
      easeInBounce: n,
      easeOutBounce: s,
      easeInOutBounce: function(t, e, i, r) {
        return t < r / 2
          ? 0.5 * n(2 * t, 0, i, r) + e
          : 0.5 * s(2 * t - r, 0, i, r) + 0.5 * i + e;
      },
    };
  })(),
  (function(t) {
    'use strict';
    var C = t.fabric || (t.fabric = {}),
      g = C.util.object.extend,
      f = C.util.object.clone,
      p = C.util.toFixed,
      S = C.util.parseUnit,
      h = C.util.multiplyTransformMatrices,
      v = {
        cx: 'left',
        x: 'left',
        r: 'radius',
        cy: 'top',
        y: 'top',
        display: 'visible',
        visibility: 'visible',
        transform: 'transformMatrix',
        'fill-opacity': 'fillOpacity',
        'fill-rule': 'fillRule',
        'font-family': 'fontFamily',
        'font-size': 'fontSize',
        'font-style': 'fontStyle',
        'font-weight': 'fontWeight',
        'letter-spacing': 'charSpacing',
        'paint-order': 'paintFirst',
        'stroke-dasharray': 'strokeDashArray',
        'stroke-dashoffset': 'strokeDashOffset',
        'stroke-linecap': 'strokeLineCap',
        'stroke-linejoin': 'strokeLineJoin',
        'stroke-miterlimit': 'strokeMiterLimit',
        'stroke-opacity': 'strokeOpacity',
        'stroke-width': 'strokeWidth',
        'text-decoration': 'textDecoration',
        'text-anchor': 'textAnchor',
        opacity: 'opacity',
        'clip-path': 'clipPath',
        'clip-rule': 'clipRule',
      },
      m = { stroke: 'strokeOpacity', fill: 'fillOpacity' };
    function b(t, e, i, r) {
      var n,
        s = '[object Array]' === Object.prototype.toString.call(e);
      if (('fill' !== t && 'stroke' !== t) || 'none' !== e)
        if ('strokeDashArray' === t)
          e =
            'none' === e
              ? null
              : e
                  .replace(/,/g, ' ')
                  .split(/\s+/)
                  .map(parseFloat);
        else if ('transformMatrix' === t)
          e =
            i && i.transformMatrix
              ? h(i.transformMatrix, C.parseTransformAttribute(e))
              : C.parseTransformAttribute(e);
        else if ('visible' === t)
          (e = 'none' !== e && 'hidden' !== e),
            i && !1 === i.visible && (e = !1);
        else if ('opacity' === t)
          (e = parseFloat(e)), i && void 0 !== i.opacity && (e *= i.opacity);
        else if ('textAnchor' === t)
          e = 'start' === e ? 'left' : 'end' === e ? 'right' : 'center';
        else if ('charSpacing' === t) n = (S(e, r) / r) * 1e3;
        else if ('paintFirst' === t) {
          var o = e.indexOf('fill'),
            a = e.indexOf('stroke');
          e = 'fill';
          -1 < o && -1 < a && a < o
            ? (e = 'stroke')
            : -1 === o && -1 < a && (e = 'stroke');
        } else {
          if ('href' === t || 'xlink:href' === t) return e;
          n = s ? e.map(S) : S(e, r);
        }
      else e = '';
      return !s && isNaN(n) ? e : n;
    }
    function e(t) {
      return new RegExp('^(' + t.join('|') + ')\\b', 'i');
    }
    function _(t, e) {
      var i,
        r,
        n,
        s,
        o = [];
      for (n = 0, s = e.length; n < s; n++)
        (i = e[n]),
          (r = t.getElementsByTagName(i)),
          (o = o.concat(Array.prototype.slice.call(r)));
      return o;
    }
    function y(t, e) {
      var i,
        r = !0;
      return (
        (i = n(t, e.pop())) &&
          e.length &&
          (r = (function(t, e) {
            var i,
              r = !0;
            for (; t.parentNode && 1 === t.parentNode.nodeType && e.length; )
              r && (i = e.pop()), (t = t.parentNode), (r = n(t, i));
            return 0 === e.length;
          })(t, e)),
        i && r && 0 === e.length
      );
    }
    function n(t, e) {
      var i,
        r,
        n = t.nodeName,
        s = t.getAttribute('class'),
        o = t.getAttribute('id');
      if (
        ((i = new RegExp('^' + n, 'i')),
        (e = e.replace(i, '')),
        o &&
          e.length &&
          ((i = new RegExp('#' + o + '(?![a-zA-Z\\-]+)', 'i')),
          (e = e.replace(i, ''))),
        s && e.length)
      )
        for (r = (s = s.split(' ')).length; r--; )
          (i = new RegExp('\\.' + s[r] + '(?![a-zA-Z\\-]+)', 'i')),
            (e = e.replace(i, ''));
      return 0 === e.length;
    }
    function x(t, e) {
      var i;
      if ((t.getElementById && (i = t.getElementById(e)), i)) return i;
      var r,
        n,
        s,
        o = t.getElementsByTagName('*');
      for (n = 0, s = o.length; n < s; n++)
        if (e === (r = o[n]).getAttribute('id')) return r;
    }
    (C.svgValidTagNamesRegEx = e([
      'path',
      'circle',
      'polygon',
      'polyline',
      'ellipse',
      'rect',
      'line',
      'image',
      'text',
    ])),
      (C.svgViewBoxElementsRegEx = e([
        'symbol',
        'image',
        'marker',
        'pattern',
        'view',
        'svg',
      ])),
      (C.svgInvalidAncestorsRegEx = e([
        'pattern',
        'defs',
        'symbol',
        'metadata',
        'clipPath',
        'mask',
        'desc',
      ])),
      (C.svgValidParentsRegEx = e([
        'symbol',
        'g',
        'a',
        'svg',
        'clipPath',
        'defs',
      ])),
      (C.cssRules = {}),
      (C.gradientDefs = {}),
      (C.clipPaths = {}),
      (C.parseTransformAttribute = (function() {
        function b(t, e, i) {
          t[i] = Math.tan(C.util.degreesToRadians(e[0]));
        }
        var _ = C.iMatrix,
          t = C.reNum,
          e = '(?:\\s+,?\\s*|,\\s*)',
          y =
            '(?:' +
            ('(?:(matrix)\\s*\\(\\s*(' +
              t +
              ')' +
              e +
              '(' +
              t +
              ')' +
              e +
              '(' +
              t +
              ')' +
              e +
              '(' +
              t +
              ')' +
              e +
              '(' +
              t +
              ')' +
              e +
              '(' +
              t +
              ')\\s*\\))') +
            '|' +
            ('(?:(translate)\\s*\\(\\s*(' +
              t +
              ')(?:' +
              e +
              '(' +
              t +
              '))?\\s*\\))') +
            '|' +
            ('(?:(scale)\\s*\\(\\s*(' +
              t +
              ')(?:' +
              e +
              '(' +
              t +
              '))?\\s*\\))') +
            '|' +
            ('(?:(rotate)\\s*\\(\\s*(' +
              t +
              ')(?:' +
              e +
              '(' +
              t +
              ')' +
              e +
              '(' +
              t +
              '))?\\s*\\))') +
            '|' +
            ('(?:(skewX)\\s*\\(\\s*(' + t + ')\\s*\\))') +
            '|' +
            ('(?:(skewY)\\s*\\(\\s*(' + t + ')\\s*\\))') +
            ')',
          i = new RegExp(
            '^\\s*(?:' + ('(?:' + y + '(?:' + e + '*' + y + ')*)') + '?)\\s*$'
          ),
          r = new RegExp(y, 'g');
        return function(t) {
          var v = _.concat(),
            m = [];
          if (!t || (t && !i.test(t))) return v;
          t.replace(r, function(t) {
            var e,
              i,
              r,
              n,
              s,
              o,
              a,
              h,
              c,
              l,
              u,
              f,
              d = new RegExp(y).exec(t).filter(function(t) {
                return !!t;
              }),
              g = d[1],
              p = d.slice(2).map(parseFloat);
            switch (g) {
              case 'translate':
                (f = p), ((u = v)[4] = f[0]), 2 === f.length && (u[5] = f[1]);
                break;
              case 'rotate':
                (p[0] = C.util.degreesToRadians(p[0])),
                  (s = v),
                  (o = p),
                  (a = C.util.cos(o[0])),
                  (h = C.util.sin(o[0])),
                  (l = c = 0),
                  3 === o.length && ((c = o[1]), (l = o[2])),
                  (s[0] = a),
                  (s[1] = h),
                  (s[2] = -h),
                  (s[3] = a),
                  (s[4] = c - (a * c - h * l)),
                  (s[5] = l - (h * c + a * l));
                break;
              case 'scale':
                (e = v),
                  (r = (i = p)[0]),
                  (n = 2 === i.length ? i[1] : i[0]),
                  (e[0] = r),
                  (e[3] = n);
                break;
              case 'skewX':
                b(v, p, 2);
                break;
              case 'skewY':
                b(v, p, 1);
                break;
              case 'matrix':
                v = p;
            }
            m.push(v.concat()), (v = _.concat());
          });
          for (var e = m[0]; 1 < m.length; )
            m.shift(), (e = C.util.multiplyTransformMatrices(e, m[0]));
          return e;
        };
      })());
    var T = new RegExp(
      '^\\s*(' +
        C.reNum +
        '+)\\s*,?\\s*(' +
        C.reNum +
        '+)\\s*,?\\s*(' +
        C.reNum +
        '+)\\s*,?\\s*(' +
        C.reNum +
        '+)\\s*$'
    );
    function w(t) {
      var e,
        i,
        r,
        n,
        s,
        o,
        a = t.getAttribute('viewBox'),
        h = 1,
        c = 1,
        l = t.getAttribute('width'),
        u = t.getAttribute('height'),
        f = t.getAttribute('x') || 0,
        d = t.getAttribute('y') || 0,
        g = t.getAttribute('preserveAspectRatio') || '',
        p =
          !a ||
          !C.svgViewBoxElementsRegEx.test(t.nodeName) ||
          !(a = a.match(T)),
        v = !l || !u || '100%' === l || '100%' === u,
        m = p && v,
        b = {},
        _ = '',
        y = 0,
        x = 0;
      if (((b.width = 0), (b.height = 0), (b.toBeParsed = m))) return b;
      if (p) return (b.width = S(l)), (b.height = S(u)), b;
      if (
        ((e = -parseFloat(a[1])),
        (i = -parseFloat(a[2])),
        (r = parseFloat(a[3])),
        (n = parseFloat(a[4])),
        v
          ? ((b.width = r), (b.height = n))
          : ((b.width = S(l)),
            (b.height = S(u)),
            (h = b.width / r),
            (c = b.height / n)),
        'none' !== (g = C.util.parsePreserveAspectRatioAttribute(g)).alignX &&
          ('meet' === g.meetOrSlice && (c = h = c < h ? c : h),
          'slice' === g.meetOrSlice && (c = h = c < h ? h : c),
          (y = b.width - r * h),
          (x = b.height - n * h),
          'Mid' === g.alignX && (y /= 2),
          'Mid' === g.alignY && (x /= 2),
          'Min' === g.alignX && (y = 0),
          'Min' === g.alignY && (x = 0)),
        1 === h && 1 === c && 0 === e && 0 === i && 0 === f && 0 === d)
      )
        return b;
      if (
        ((f || d) && (_ = ' translate(' + S(f) + ' ' + S(d) + ') '),
        (s =
          _ +
          ' matrix(' +
          h +
          ' 0 0 ' +
          c +
          ' ' +
          (e * h + y) +
          ' ' +
          (i * c + x) +
          ') '),
        (b.viewboxTransform = C.parseTransformAttribute(s)),
        'svg' === t.nodeName)
      ) {
        for (o = t.ownerDocument.createElement('g'); t.firstChild; )
          o.appendChild(t.firstChild);
        t.appendChild(o);
      } else s = (o = t).getAttribute('transform') + s;
      return o.setAttribute('transform', s), b;
    }
    function s(t, e) {
      var i = 'xlink:href',
        r = x(t, e.getAttribute(i).substr(1));
      if (
        (r && r.getAttribute(i) && s(t, r),
        [
          'gradientTransform',
          'x1',
          'x2',
          'y1',
          'y2',
          'gradientUnits',
          'cx',
          'cy',
          'r',
          'fx',
          'fy',
        ].forEach(function(t) {
          e.hasAttribute(t) || e.setAttribute(t, r.getAttribute(t));
        }),
        !e.children.length)
      )
        for (var n = r.cloneNode(!0); n.firstChild; )
          e.appendChild(n.firstChild);
      e.removeAttribute(i);
    }
    C.parseSVGDocument = function(t, i, e, r) {
      if (t) {
        !(function(t) {
          for (
            var e = _(t, ['use', 'svg:use']), i = 0;
            e.length && i < e.length;

          ) {
            var r,
              n,
              s,
              o,
              a = e[i],
              h = (
                a.getAttribute('xlink:href') || a.getAttribute('href')
              ).substr(1),
              c = a.getAttribute('x') || 0,
              l = a.getAttribute('y') || 0,
              u = x(t, h).cloneNode(!0),
              f =
                (u.getAttribute('transform') || '') +
                ' translate(' +
                c +
                ', ' +
                l +
                ')',
              d = e.length;
            if ((w(u), /^svg$/i.test(u.nodeName))) {
              var g = u.ownerDocument.createElement('g');
              for (n = 0, o = (s = u.attributes).length; n < o; n++)
                (r = s.item(n)), g.setAttribute(r.nodeName, r.nodeValue);
              for (; u.firstChild; ) g.appendChild(u.firstChild);
              u = g;
            }
            for (n = 0, o = (s = a.attributes).length; n < o; n++)
              'x' !== (r = s.item(n)).nodeName &&
                'y' !== r.nodeName &&
                'xlink:href' !== r.nodeName &&
                'href' !== r.nodeName &&
                ('transform' === r.nodeName
                  ? (f = r.nodeValue + ' ' + f)
                  : u.setAttribute(r.nodeName, r.nodeValue));
            u.setAttribute('transform', f),
              u.setAttribute('instantiated_by_use', '1'),
              u.removeAttribute('id'),
              a.parentNode.replaceChild(u, a),
              e.length === d && i++;
          }
        })(t);
        var n,
          s,
          o = C.Object.__uid++,
          a = w(t),
          h = C.util.toArray(t.getElementsByTagName('*'));
        if (
          ((a.crossOrigin = r && r.crossOrigin),
          (a.svgUid = o),
          0 === h.length && C.isLikelyNode)
        ) {
          var c = [];
          for (
            n = 0, s = (h = t.selectNodes('//*[name(.)!="svg"]')).length;
            n < s;
            n++
          )
            c[n] = h[n];
          h = c;
        }
        var l = h.filter(function(t) {
          return (
            w(t),
            C.svgValidTagNamesRegEx.test(t.nodeName.replace('svg:', '')) &&
              !(function(t, e) {
                for (; t && (t = t.parentNode); )
                  if (
                    t.nodeName &&
                    e.test(t.nodeName.replace('svg:', '')) &&
                    !t.getAttribute('instantiated_by_use')
                  )
                    return !0;
                return !1;
              })(t, C.svgInvalidAncestorsRegEx)
          );
        });
        if (!l || (l && !l.length)) i && i([], {});
        else {
          var u = {};
          h
            .filter(function(t) {
              return 'clipPath' === t.nodeName.replace('svg:', '');
            })
            .forEach(function(t) {
              var e = t.getAttribute('id');
              u[e] = C.util
                .toArray(t.getElementsByTagName('*'))
                .filter(function(t) {
                  return C.svgValidTagNamesRegEx.test(
                    t.nodeName.replace('svg:', '')
                  );
                });
            }),
            (C.gradientDefs[o] = C.getGradientDefs(t)),
            (C.cssRules[o] = C.getCSSRules(t)),
            (C.clipPaths[o] = u),
            C.parseElements(
              l,
              function(t, e) {
                i &&
                  (i(t, a, e, h),
                  delete C.gradientDefs[o],
                  delete C.cssRules[o],
                  delete C.clipPaths[o]);
              },
              f(a),
              e,
              r
            );
        }
      }
    };
    var c = new RegExp(
      '(normal|italic)?\\s*(normal|small-caps)?\\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(' +
        C.reNum +
        '(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|' +
        C.reNum +
        '))?\\s+(.*)'
    );
    g(C, {
      parseFontDeclaration: function(t, e) {
        var i = t.match(c);
        if (i) {
          var r = i[1],
            n = i[3],
            s = i[4],
            o = i[5],
            a = i[6];
          r && (e.fontStyle = r),
            n && (e.fontWeight = isNaN(parseFloat(n)) ? n : parseFloat(n)),
            s && (e.fontSize = S(s)),
            a && (e.fontFamily = a),
            o && (e.lineHeight = 'normal' === o ? 1 : o);
        }
      },
      getGradientDefs: function(t) {
        var e,
          i = _(t, [
            'linearGradient',
            'radialGradient',
            'svg:linearGradient',
            'svg:radialGradient',
          ]),
          r = 0,
          n = {};
        for (r = i.length; r--; )
          (e = i[r]).getAttribute('xlink:href') && s(t, e),
            (n[e.getAttribute('id')] = e);
        return n;
      },
      parseAttributes: function(i, t, e) {
        if (i) {
          var r,
            n,
            s,
            o = {};
          void 0 === e && (e = i.getAttribute('svgUid')),
            i.parentNode &&
              C.svgValidParentsRegEx.test(i.parentNode.nodeName) &&
              (o = C.parseAttributes(i.parentNode, t, e));
          var a = t.reduce(function(t, e) {
            return (r = i.getAttribute(e)) && (t[e] = r), t;
          }, {});
          (a = g(
            a,
            g(
              (function(t, e) {
                var i = {};
                for (var r in C.cssRules[e])
                  if (y(t, r.split(' ')))
                    for (var n in C.cssRules[e][r]) i[n] = C.cssRules[e][r][n];
                return i;
              })(i, e),
              C.parseStyleAttribute(i)
            )
          )),
            (n = s = o.fontSize || C.Text.DEFAULT_SVG_FONT_SIZE),
            a['font-size'] && (a['font-size'] = n = S(a['font-size'], s));
          var h,
            c,
            l,
            u = {};
          for (var f in a)
            (c = b((h = (l = f) in v ? v[l] : l), a[f], o, n)), (u[h] = c);
          u && u.font && C.parseFontDeclaration(u.font, u);
          var d = g(o, u);
          return C.svgValidParentsRegEx.test(i.nodeName)
            ? d
            : (function(t) {
                for (var e in m)
                  if (void 0 !== t[m[e]] && '' !== t[e]) {
                    if (void 0 === t[e]) {
                      if (!C.Object.prototype[e]) continue;
                      t[e] = C.Object.prototype[e];
                    }
                    if (0 !== t[e].indexOf('url(')) {
                      var i = new C.Color(t[e]);
                      t[e] = i.setAlpha(p(i.getAlpha() * t[m[e]], 2)).toRgba();
                    }
                  }
                return t;
              })(d);
        }
      },
      parseElements: function(t, e, i, r, n) {
        new C.ElementsParser(t, e, i, r, n).parse();
      },
      parseStyleAttribute: function(t) {
        var i,
          r,
          n,
          e = {},
          s = t.getAttribute('style');
        return (
          s &&
            ('string' == typeof s
              ? ((i = e),
                s
                  .replace(/;\s*$/, '')
                  .split(';')
                  .forEach(function(t) {
                    var e = t.split(':');
                    (r = e[0].trim().toLowerCase()),
                      (n = e[1].trim()),
                      (i[r] = n);
                  }))
              : (function(t, e) {
                  var i, r;
                  for (var n in t)
                    void 0 !== t[n] &&
                      ((i = n.toLowerCase()), (r = t[n]), (e[i] = r));
                })(s, e)),
          e
        );
      },
      parsePointsAttribute: function(t) {
        if (!t) return null;
        var e,
          i,
          r = [];
        for (
          e = 0,
            i = (t = (t = t.replace(/,/g, ' ').trim()).split(/\s+/)).length;
          e < i;
          e += 2
        )
          r.push({ x: parseFloat(t[e]), y: parseFloat(t[e + 1]) });
        return r;
      },
      getCSSRules: function(t) {
        var a,
          h,
          e = t.getElementsByTagName('style'),
          c = {};
        for (a = 0, h = e.length; a < h; a++) {
          var i = e[a].textContent || e[a].text;
          '' !== (i = i.replace(/\/\*[\s\S]*?\*\//g, '')).trim() &&
            i
              .match(/[^{]*\{[\s\S]*?\}/g)
              .map(function(t) {
                return t.trim();
              })
              .forEach(function(t) {
                var e = t.match(/([\s\S]*?)\s*\{([^}]*)\}/),
                  i = {},
                  r = e[2]
                    .trim()
                    .replace(/;$/, '')
                    .split(/\s*;\s*/);
                for (a = 0, h = r.length; a < h; a++) {
                  var n = r[a].split(/\s*:\s*/),
                    s = n[0],
                    o = n[1];
                  i[s] = o;
                }
                (t = e[1]).split(',').forEach(function(t) {
                  '' !== (t = t.replace(/^svg/i, '').trim()) &&
                    (c[t]
                      ? C.util.object.extend(c[t], i)
                      : (c[t] = C.util.object.clone(i)));
                });
              });
        }
        return c;
      },
      loadSVGFromURL: function(t, n, i, r) {
        (t = t.replace(/^\n\s*/, '').trim()),
          new C.util.request(t, {
            method: 'get',
            onComplete: function(t) {
              var e = t.responseXML;
              e &&
                !e.documentElement &&
                C.window.ActiveXObject &&
                t.responseText &&
                (((e = new ActiveXObject('Microsoft.XMLDOM')).async = 'false'),
                e.loadXML(
                  t.responseText.replace(
                    /<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i,
                    ''
                  )
                ));
              if (!e || !e.documentElement) return n && n(null), !1;
              C.parseSVGDocument(
                e.documentElement,
                function(t, e, i, r) {
                  n && n(t, e, i, r);
                },
                i,
                r
              );
            },
          });
      },
      loadSVGFromString: function(t, n, e, i) {
        var r;
        if (((t = t.trim()), 'undefined' != typeof DOMParser)) {
          var s = new DOMParser();
          s && s.parseFromString && (r = s.parseFromString(t, 'text/xml'));
        } else
          C.window.ActiveXObject &&
            (((r = new ActiveXObject('Microsoft.XMLDOM')).async = 'false'),
            r.loadXML(t.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i, '')));
        C.parseSVGDocument(
          r.documentElement,
          function(t, e, i, r) {
            n(t, e, i, r);
          },
          e,
          i
        );
      },
    });
  })('undefined' != typeof exports ? exports : this),
  (fabric.ElementsParser = function(t, e, i, r, n) {
    (this.elements = t),
      (this.callback = e),
      (this.options = i),
      (this.reviver = r),
      (this.svgUid = (i && i.svgUid) || 0),
      (this.parsingOptions = n),
      (this.regexUrl = /^url\(['"]?#([^'"]+)['"]?\)/g);
  }),
  (function(t) {
    (t.parse = function() {
      (this.instances = new Array(this.elements.length)),
        (this.numElements = this.elements.length),
        this.createObjects();
    }),
      (t.createObjects = function() {
        var i = this;
        this.elements.forEach(function(t, e) {
          t.setAttribute('svgUid', i.svgUid), i.createObject(t, e);
        });
      }),
      (t.findTag = function(t) {
        return fabric[
          fabric.util.string.capitalize(t.tagName.replace('svg:', ''))
        ];
      }),
      (t.createObject = function(t, e) {
        var i = this.findTag(t);
        if (i && i.fromElement)
          try {
            i.fromElement(t, this.createCallback(e, t), this.options);
          } catch (t) {
            fabric.log(t);
          }
        else this.checkIfDone();
      }),
      (t.createCallback = function(i, r) {
        var n = this;
        return function(t) {
          var e;
          n.resolveGradient(t, 'fill'),
            n.resolveGradient(t, 'stroke'),
            t instanceof fabric.Image &&
              t._originalElement &&
              (e = t.parsePreserveAspectRatioAttribute(r)),
            t._removeTransformMatrix(e),
            n.resolveClipPath(t),
            n.reviver && n.reviver(r, t),
            (n.instances[i] = t),
            n.checkIfDone();
        };
      }),
      (t.extractPropertyDefinition = function(t, e, i) {
        var r = t[e];
        if (/^url\(/.test(r)) {
          var n = this.regexUrl.exec(r)[1];
          return (this.regexUrl.lastIndex = 0), fabric[i][this.svgUid][n];
        }
      }),
      (t.resolveGradient = function(t, e) {
        var i = this.extractPropertyDefinition(t, e, 'gradientDefs');
        i && t.set(e, fabric.Gradient.fromElement(i, t));
      }),
      (t.createClipPathCallback = function(t, e) {
        return function(t) {
          t._removeTransformMatrix(), (t.fillRule = t.clipRule), e.push(t);
        };
      }),
      (t.resolveClipPath = function(t) {
        var e,
          i,
          r,
          n,
          s = this.extractPropertyDefinition(t, 'clipPath', 'clipPaths');
        if (s) {
          (r = []), (i = fabric.util.invertTransform(t.calcTransformMatrix()));
          for (var o = 0; o < s.length; o++)
            (e = s[o]),
              this.findTag(e).fromElement(
                e,
                this.createClipPathCallback(t, r),
                this.options
              );
          (s = 1 === r.length ? r[0] : new fabric.Group(r)),
            (n = fabric.util.multiplyTransformMatrices(
              i,
              s.calcTransformMatrix()
            ));
          var a = fabric.util.qrDecompose(n);
          (s.flipX = !1),
            (s.flipY = !1),
            s.set('scaleX', a.scaleX),
            s.set('scaleY', a.scaleY),
            (s.angle = a.angle),
            (s.skewX = a.skewX),
            (s.skewY = 0),
            s.setPositionByOrigin(
              { x: a.translateX, y: a.translateY },
              'center',
              'center'
            ),
            (t.clipPath = s);
        }
      }),
      (t.checkIfDone = function() {
        0 == --this.numElements &&
          ((this.instances = this.instances.filter(function(t) {
            return null != t;
          })),
          this.callback(this.instances, this.elements));
      });
  })(fabric.ElementsParser.prototype),
  (function(t) {
    'use strict';
    var e = t.fabric || (t.fabric = {});
    function i(t, e) {
      (this.x = t), (this.y = e);
    }
    e.Point
      ? e.warn('fabric.Point is already defined')
      : ((e.Point = i).prototype = {
          type: 'point',
          constructor: i,
          add: function(t) {
            return new i(this.x + t.x, this.y + t.y);
          },
          addEquals: function(t) {
            return (this.x += t.x), (this.y += t.y), this;
          },
          scalarAdd: function(t) {
            return new i(this.x + t, this.y + t);
          },
          scalarAddEquals: function(t) {
            return (this.x += t), (this.y += t), this;
          },
          subtract: function(t) {
            return new i(this.x - t.x, this.y - t.y);
          },
          subtractEquals: function(t) {
            return (this.x -= t.x), (this.y -= t.y), this;
          },
          scalarSubtract: function(t) {
            return new i(this.x - t, this.y - t);
          },
          scalarSubtractEquals: function(t) {
            return (this.x -= t), (this.y -= t), this;
          },
          multiply: function(t) {
            return new i(this.x * t, this.y * t);
          },
          multiplyEquals: function(t) {
            return (this.x *= t), (this.y *= t), this;
          },
          divide: function(t) {
            return new i(this.x / t, this.y / t);
          },
          divideEquals: function(t) {
            return (this.x /= t), (this.y /= t), this;
          },
          eq: function(t) {
            return this.x === t.x && this.y === t.y;
          },
          lt: function(t) {
            return this.x < t.x && this.y < t.y;
          },
          lte: function(t) {
            return this.x <= t.x && this.y <= t.y;
          },
          gt: function(t) {
            return this.x > t.x && this.y > t.y;
          },
          gte: function(t) {
            return this.x >= t.x && this.y >= t.y;
          },
          lerp: function(t, e) {
            return (
              void 0 === e && (e = 0.5),
              (e = Math.max(Math.min(1, e), 0)),
              new i(this.x + (t.x - this.x) * e, this.y + (t.y - this.y) * e)
            );
          },
          distanceFrom: function(t) {
            var e = this.x - t.x,
              i = this.y - t.y;
            return Math.sqrt(e * e + i * i);
          },
          midPointFrom: function(t) {
            return this.lerp(t);
          },
          min: function(t) {
            return new i(Math.min(this.x, t.x), Math.min(this.y, t.y));
          },
          max: function(t) {
            return new i(Math.max(this.x, t.x), Math.max(this.y, t.y));
          },
          toString: function() {
            return this.x + ',' + this.y;
          },
          setXY: function(t, e) {
            return (this.x = t), (this.y = e), this;
          },
          setX: function(t) {
            return (this.x = t), this;
          },
          setY: function(t) {
            return (this.y = t), this;
          },
          setFromPoint: function(t) {
            return (this.x = t.x), (this.y = t.y), this;
          },
          swap: function(t) {
            var e = this.x,
              i = this.y;
            (this.x = t.x), (this.y = t.y), (t.x = e), (t.y = i);
          },
          clone: function() {
            return new i(this.x, this.y);
          },
        });
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var f = t.fabric || (t.fabric = {});
    function d(t) {
      (this.status = t), (this.points = []);
    }
    f.Intersection
      ? f.warn('fabric.Intersection is already defined')
      : ((f.Intersection = d),
        (f.Intersection.prototype = {
          constructor: d,
          appendPoint: function(t) {
            return this.points.push(t), this;
          },
          appendPoints: function(t) {
            return (this.points = this.points.concat(t)), this;
          },
        }),
        (f.Intersection.intersectLineLine = function(t, e, i, r) {
          var n,
            s = (r.x - i.x) * (t.y - i.y) - (r.y - i.y) * (t.x - i.x),
            o = (e.x - t.x) * (t.y - i.y) - (e.y - t.y) * (t.x - i.x),
            a = (r.y - i.y) * (e.x - t.x) - (r.x - i.x) * (e.y - t.y);
          if (0 !== a) {
            var h = s / a,
              c = o / a;
            0 <= h && h <= 1 && 0 <= c && c <= 1
              ? (n = new d('Intersection')).appendPoint(
                  new f.Point(t.x + h * (e.x - t.x), t.y + h * (e.y - t.y))
                )
              : (n = new d());
          } else n = new d(0 === s || 0 === o ? 'Coincident' : 'Parallel');
          return n;
        }),
        (f.Intersection.intersectLinePolygon = function(t, e, i) {
          var r,
            n,
            s,
            o,
            a = new d(),
            h = i.length;
          for (o = 0; o < h; o++)
            (r = i[o]),
              (n = i[(o + 1) % h]),
              (s = d.intersectLineLine(t, e, r, n)),
              a.appendPoints(s.points);
          return 0 < a.points.length && (a.status = 'Intersection'), a;
        }),
        (f.Intersection.intersectPolygonPolygon = function(t, e) {
          var i,
            r = new d(),
            n = t.length;
          for (i = 0; i < n; i++) {
            var s = t[i],
              o = t[(i + 1) % n],
              a = d.intersectLinePolygon(s, o, e);
            r.appendPoints(a.points);
          }
          return 0 < r.points.length && (r.status = 'Intersection'), r;
        }),
        (f.Intersection.intersectPolygonRectangle = function(t, e, i) {
          var r = e.min(i),
            n = e.max(i),
            s = new f.Point(n.x, r.y),
            o = new f.Point(r.x, n.y),
            a = d.intersectLinePolygon(r, s, t),
            h = d.intersectLinePolygon(s, n, t),
            c = d.intersectLinePolygon(n, o, t),
            l = d.intersectLinePolygon(o, r, t),
            u = new d();
          return (
            u.appendPoints(a.points),
            u.appendPoints(h.points),
            u.appendPoints(c.points),
            u.appendPoints(l.points),
            0 < u.points.length && (u.status = 'Intersection'),
            u
          );
        }));
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var c = t.fabric || (t.fabric = {});
    function l(t) {
      t ? this._tryParsingColor(t) : this.setSource([0, 0, 0, 1]);
    }
    function u(t, e, i) {
      return (
        i < 0 && (i += 1),
        1 < i && (i -= 1),
        i < 1 / 6
          ? t + 6 * (e - t) * i
          : i < 0.5
          ? e
          : i < 2 / 3
          ? t + (e - t) * (2 / 3 - i) * 6
          : t
      );
    }
    c.Color
      ? c.warn('fabric.Color is already defined.')
      : ((c.Color = l),
        (c.Color.prototype = {
          _tryParsingColor: function(t) {
            var e;
            t in l.colorNameMap && (t = l.colorNameMap[t]),
              'transparent' === t && (e = [255, 255, 255, 0]),
              e || (e = l.sourceFromHex(t)),
              e || (e = l.sourceFromRgb(t)),
              e || (e = l.sourceFromHsl(t)),
              e || (e = [0, 0, 0, 1]),
              e && this.setSource(e);
          },
          _rgbToHsl: function(t, e, i) {
            (t /= 255), (e /= 255), (i /= 255);
            var r,
              n,
              s,
              o = c.util.array.max([t, e, i]),
              a = c.util.array.min([t, e, i]);
            if (((s = (o + a) / 2), o === a)) r = n = 0;
            else {
              var h = o - a;
              switch (((n = 0.5 < s ? h / (2 - o - a) : h / (o + a)), o)) {
                case t:
                  r = (e - i) / h + (e < i ? 6 : 0);
                  break;
                case e:
                  r = (i - t) / h + 2;
                  break;
                case i:
                  r = (t - e) / h + 4;
              }
              r /= 6;
            }
            return [
              Math.round(360 * r),
              Math.round(100 * n),
              Math.round(100 * s),
            ];
          },
          getSource: function() {
            return this._source;
          },
          setSource: function(t) {
            this._source = t;
          },
          toRgb: function() {
            var t = this.getSource();
            return 'rgb(' + t[0] + ',' + t[1] + ',' + t[2] + ')';
          },
          toRgba: function() {
            var t = this.getSource();
            return 'rgba(' + t[0] + ',' + t[1] + ',' + t[2] + ',' + t[3] + ')';
          },
          toHsl: function() {
            var t = this.getSource(),
              e = this._rgbToHsl(t[0], t[1], t[2]);
            return 'hsl(' + e[0] + ',' + e[1] + '%,' + e[2] + '%)';
          },
          toHsla: function() {
            var t = this.getSource(),
              e = this._rgbToHsl(t[0], t[1], t[2]);
            return (
              'hsla(' + e[0] + ',' + e[1] + '%,' + e[2] + '%,' + t[3] + ')'
            );
          },
          toHex: function() {
            var t,
              e,
              i,
              r = this.getSource();
            return (
              (t = 1 === (t = r[0].toString(16)).length ? '0' + t : t),
              (e = 1 === (e = r[1].toString(16)).length ? '0' + e : e),
              (i = 1 === (i = r[2].toString(16)).length ? '0' + i : i),
              t.toUpperCase() + e.toUpperCase() + i.toUpperCase()
            );
          },
          toHexa: function() {
            var t,
              e = this.getSource();
            return (
              (t =
                1 === (t = (t = Math.round(255 * e[3])).toString(16)).length
                  ? '0' + t
                  : t),
              this.toHex() + t.toUpperCase()
            );
          },
          getAlpha: function() {
            return this.getSource()[3];
          },
          setAlpha: function(t) {
            var e = this.getSource();
            return (e[3] = t), this.setSource(e), this;
          },
          toGrayscale: function() {
            var t = this.getSource(),
              e = parseInt(
                (0.3 * t[0] + 0.59 * t[1] + 0.11 * t[2]).toFixed(0),
                10
              ),
              i = t[3];
            return this.setSource([e, e, e, i]), this;
          },
          toBlackWhite: function(t) {
            var e = this.getSource(),
              i = (0.3 * e[0] + 0.59 * e[1] + 0.11 * e[2]).toFixed(0),
              r = e[3];
            return (
              (t = t || 127),
              (i = Number(i) < Number(t) ? 0 : 255),
              this.setSource([i, i, i, r]),
              this
            );
          },
          overlayWith: function(t) {
            t instanceof l || (t = new l(t));
            var e,
              i = [],
              r = this.getAlpha(),
              n = this.getSource(),
              s = t.getSource();
            for (e = 0; e < 3; e++) i.push(Math.round(0.5 * n[e] + 0.5 * s[e]));
            return (i[3] = r), this.setSource(i), this;
          },
        }),
        (c.Color.reRGBa = /^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*((?:\d*\.?\d+)?)\s*)?\)$/i),
        (c.Color.reHSLa = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/i),
        (c.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i),
        (c.Color.colorNameMap = {
          aliceblue: '#F0F8FF',
          antiquewhite: '#FAEBD7',
          aqua: '#00FFFF',
          aquamarine: '#7FFFD4',
          azure: '#F0FFFF',
          beige: '#F5F5DC',
          bisque: '#FFE4C4',
          black: '#000000',
          blanchedalmond: '#FFEBCD',
          blue: '#0000FF',
          blueviolet: '#8A2BE2',
          brown: '#A52A2A',
          burlywood: '#DEB887',
          cadetblue: '#5F9EA0',
          chartreuse: '#7FFF00',
          chocolate: '#D2691E',
          coral: '#FF7F50',
          cornflowerblue: '#6495ED',
          cornsilk: '#FFF8DC',
          crimson: '#DC143C',
          cyan: '#00FFFF',
          darkblue: '#00008B',
          darkcyan: '#008B8B',
          darkgoldenrod: '#B8860B',
          darkgray: '#A9A9A9',
          darkgrey: '#A9A9A9',
          darkgreen: '#006400',
          darkkhaki: '#BDB76B',
          darkmagenta: '#8B008B',
          darkolivegreen: '#556B2F',
          darkorange: '#FF8C00',
          darkorchid: '#9932CC',
          darkred: '#8B0000',
          darksalmon: '#E9967A',
          darkseagreen: '#8FBC8F',
          darkslateblue: '#483D8B',
          darkslategray: '#2F4F4F',
          darkslategrey: '#2F4F4F',
          darkturquoise: '#00CED1',
          darkviolet: '#9400D3',
          deeppink: '#FF1493',
          deepskyblue: '#00BFFF',
          dimgray: '#696969',
          dimgrey: '#696969',
          dodgerblue: '#1E90FF',
          firebrick: '#B22222',
          floralwhite: '#FFFAF0',
          forestgreen: '#228B22',
          fuchsia: '#FF00FF',
          gainsboro: '#DCDCDC',
          ghostwhite: '#F8F8FF',
          gold: '#FFD700',
          goldenrod: '#DAA520',
          gray: '#808080',
          grey: '#808080',
          green: '#008000',
          greenyellow: '#ADFF2F',
          honeydew: '#F0FFF0',
          hotpink: '#FF69B4',
          indianred: '#CD5C5C',
          indigo: '#4B0082',
          ivory: '#FFFFF0',
          khaki: '#F0E68C',
          lavender: '#E6E6FA',
          lavenderblush: '#FFF0F5',
          lawngreen: '#7CFC00',
          lemonchiffon: '#FFFACD',
          lightblue: '#ADD8E6',
          lightcoral: '#F08080',
          lightcyan: '#E0FFFF',
          lightgoldenrodyellow: '#FAFAD2',
          lightgray: '#D3D3D3',
          lightgrey: '#D3D3D3',
          lightgreen: '#90EE90',
          lightpink: '#FFB6C1',
          lightsalmon: '#FFA07A',
          lightseagreen: '#20B2AA',
          lightskyblue: '#87CEFA',
          lightslategray: '#778899',
          lightslategrey: '#778899',
          lightsteelblue: '#B0C4DE',
          lightyellow: '#FFFFE0',
          lime: '#00FF00',
          limegreen: '#32CD32',
          linen: '#FAF0E6',
          magenta: '#FF00FF',
          maroon: '#800000',
          mediumaquamarine: '#66CDAA',
          mediumblue: '#0000CD',
          mediumorchid: '#BA55D3',
          mediumpurple: '#9370DB',
          mediumseagreen: '#3CB371',
          mediumslateblue: '#7B68EE',
          mediumspringgreen: '#00FA9A',
          mediumturquoise: '#48D1CC',
          mediumvioletred: '#C71585',
          midnightblue: '#191970',
          mintcream: '#F5FFFA',
          mistyrose: '#FFE4E1',
          moccasin: '#FFE4B5',
          navajowhite: '#FFDEAD',
          navy: '#000080',
          oldlace: '#FDF5E6',
          olive: '#808000',
          olivedrab: '#6B8E23',
          orange: '#FFA500',
          orangered: '#FF4500',
          orchid: '#DA70D6',
          palegoldenrod: '#EEE8AA',
          palegreen: '#98FB98',
          paleturquoise: '#AFEEEE',
          palevioletred: '#DB7093',
          papayawhip: '#FFEFD5',
          peachpuff: '#FFDAB9',
          peru: '#CD853F',
          pink: '#FFC0CB',
          plum: '#DDA0DD',
          powderblue: '#B0E0E6',
          purple: '#800080',
          rebeccapurple: '#663399',
          red: '#FF0000',
          rosybrown: '#BC8F8F',
          royalblue: '#4169E1',
          saddlebrown: '#8B4513',
          salmon: '#FA8072',
          sandybrown: '#F4A460',
          seagreen: '#2E8B57',
          seashell: '#FFF5EE',
          sienna: '#A0522D',
          silver: '#C0C0C0',
          skyblue: '#87CEEB',
          slateblue: '#6A5ACD',
          slategray: '#708090',
          slategrey: '#708090',
          snow: '#FFFAFA',
          springgreen: '#00FF7F',
          steelblue: '#4682B4',
          tan: '#D2B48C',
          teal: '#008080',
          thistle: '#D8BFD8',
          tomato: '#FF6347',
          turquoise: '#40E0D0',
          violet: '#EE82EE',
          wheat: '#F5DEB3',
          white: '#FFFFFF',
          whitesmoke: '#F5F5F5',
          yellow: '#FFFF00',
          yellowgreen: '#9ACD32',
        }),
        (c.Color.fromRgb = function(t) {
          return l.fromSource(l.sourceFromRgb(t));
        }),
        (c.Color.sourceFromRgb = function(t) {
          var e = t.match(l.reRGBa);
          if (e) {
            var i =
                (parseInt(e[1], 10) / (/%$/.test(e[1]) ? 100 : 1)) *
                (/%$/.test(e[1]) ? 255 : 1),
              r =
                (parseInt(e[2], 10) / (/%$/.test(e[2]) ? 100 : 1)) *
                (/%$/.test(e[2]) ? 255 : 1),
              n =
                (parseInt(e[3], 10) / (/%$/.test(e[3]) ? 100 : 1)) *
                (/%$/.test(e[3]) ? 255 : 1);
            return [
              parseInt(i, 10),
              parseInt(r, 10),
              parseInt(n, 10),
              e[4] ? parseFloat(e[4]) : 1,
            ];
          }
        }),
        (c.Color.fromRgba = l.fromRgb),
        (c.Color.fromHsl = function(t) {
          return l.fromSource(l.sourceFromHsl(t));
        }),
        (c.Color.sourceFromHsl = function(t) {
          var e = t.match(l.reHSLa);
          if (e) {
            var i,
              r,
              n,
              s = (((parseFloat(e[1]) % 360) + 360) % 360) / 360,
              o = parseFloat(e[2]) / (/%$/.test(e[2]) ? 100 : 1),
              a = parseFloat(e[3]) / (/%$/.test(e[3]) ? 100 : 1);
            if (0 === o) i = r = n = a;
            else {
              var h = a <= 0.5 ? a * (o + 1) : a + o - a * o,
                c = 2 * a - h;
              (i = u(c, h, s + 1 / 3)),
                (r = u(c, h, s)),
                (n = u(c, h, s - 1 / 3));
            }
            return [
              Math.round(255 * i),
              Math.round(255 * r),
              Math.round(255 * n),
              e[4] ? parseFloat(e[4]) : 1,
            ];
          }
        }),
        (c.Color.fromHsla = l.fromHsl),
        (c.Color.fromHex = function(t) {
          return l.fromSource(l.sourceFromHex(t));
        }),
        (c.Color.sourceFromHex = function(t) {
          if (t.match(l.reHex)) {
            var e = t.slice(t.indexOf('#') + 1),
              i = 3 === e.length || 4 === e.length,
              r = 8 === e.length || 4 === e.length,
              n = i ? e.charAt(0) + e.charAt(0) : e.substring(0, 2),
              s = i ? e.charAt(1) + e.charAt(1) : e.substring(2, 4),
              o = i ? e.charAt(2) + e.charAt(2) : e.substring(4, 6),
              a = r
                ? i
                  ? e.charAt(3) + e.charAt(3)
                  : e.substring(6, 8)
                : 'FF';
            return [
              parseInt(n, 16),
              parseInt(s, 16),
              parseInt(o, 16),
              parseFloat((parseInt(a, 16) / 255).toFixed(2)),
            ];
          }
        }),
        (c.Color.fromSource = function(t) {
          var e = new l();
          return e.setSource(t), e;
        }));
  })('undefined' != typeof exports ? exports : this),
  (function() {
    function d(t) {
      var e,
        i,
        r,
        n,
        s = t.getAttribute('style'),
        o = t.getAttribute('offset') || 0;
      if (
        ((o =
          (o = parseFloat(o) / (/%$/.test(o) ? 100 : 1)) < 0
            ? 0
            : 1 < o
            ? 1
            : o),
        s)
      ) {
        var a = s.split(/\s*;\s*/);
        for ('' === a[a.length - 1] && a.pop(), n = a.length; n--; ) {
          var h = a[n].split(/\s*:\s*/),
            c = h[0].trim(),
            l = h[1].trim();
          'stop-color' === c ? (e = l) : 'stop-opacity' === c && (r = l);
        }
      }
      return (
        e || (e = t.getAttribute('stop-color') || 'rgb(0,0,0)'),
        r || (r = t.getAttribute('stop-opacity')),
        (i = (e = new fabric.Color(e)).getAlpha()),
        (r = isNaN(parseFloat(r)) ? 1 : parseFloat(r)),
        (r *= i),
        { offset: o, color: e.toRgb(), opacity: r }
      );
    }
    var g = fabric.util.object.clone;
    function p(t, e, i) {
      var r,
        n = 0,
        s = 1,
        o = '';
      for (var a in e)
        'Infinity' === e[a] ? (e[a] = 1) : '-Infinity' === e[a] && (e[a] = 0),
          (r = parseFloat(e[a], 10)),
          (s =
            'string' == typeof e[a] && /^(\d+\.\d+)%|(\d+)%$/.test(e[a])
              ? 0.01
              : 1),
          'x1' === a || 'x2' === a || 'r2' === a
            ? ((s *= 'objectBoundingBox' === i ? t.width : 1),
              (n = ('objectBoundingBox' === i && t.left) || 0))
            : ('y1' !== a && 'y2' !== a) ||
              ((s *= 'objectBoundingBox' === i ? t.height : 1),
              (n = ('objectBoundingBox' === i && t.top) || 0)),
          (e[a] = r * s + n);
      if (
        'ellipse' === t.type &&
        null !== e.r2 &&
        'objectBoundingBox' === i &&
        t.rx !== t.ry
      ) {
        var h = t.ry / t.rx;
        (o = ' scale(1, ' + h + ')'), e.y1 && (e.y1 /= h), e.y2 && (e.y2 /= h);
      }
      return o;
    }
    (fabric.Gradient = fabric.util.createClass({
      offsetX: 0,
      offsetY: 0,
      initialize: function(t) {
        t || (t = {});
        var e = {};
        (this.id = fabric.Object.__uid++),
          (this.type = t.type || 'linear'),
          (e = {
            x1: t.coords.x1 || 0,
            y1: t.coords.y1 || 0,
            x2: t.coords.x2 || 0,
            y2: t.coords.y2 || 0,
          }),
          'radial' === this.type &&
            ((e.r1 = t.coords.r1 || 0), (e.r2 = t.coords.r2 || 0)),
          (this.coords = e),
          (this.colorStops = t.colorStops.slice()),
          t.gradientTransform && (this.gradientTransform = t.gradientTransform),
          (this.offsetX = t.offsetX || this.offsetX),
          (this.offsetY = t.offsetY || this.offsetY);
      },
      addColorStop: function(t) {
        for (var e in t) {
          var i = new fabric.Color(t[e]);
          this.colorStops.push({
            offset: parseFloat(e),
            color: i.toRgb(),
            opacity: i.getAlpha(),
          });
        }
        return this;
      },
      toObject: function(t) {
        var e = {
          type: this.type,
          coords: this.coords,
          colorStops: this.colorStops,
          offsetX: this.offsetX,
          offsetY: this.offsetY,
          gradientTransform: this.gradientTransform
            ? this.gradientTransform.concat()
            : this.gradientTransform,
        };
        return fabric.util.populateWithProperties(this, e, t), e;
      },
      toSVG: function(t) {
        var e,
          i,
          r,
          n,
          s = g(this.coords, !0),
          o = g(this.colorStops, !0),
          a = s.r1 > s.r2,
          h = t.width / 2,
          c = t.height / 2;
        for (var l in (o.sort(function(t, e) {
          return t.offset - e.offset;
        }),
        'path' === t.type && ((h -= t.pathOffset.x), (c -= t.pathOffset.y)),
        s))
          'x1' === l || 'x2' === l
            ? (s[l] += this.offsetX - h)
            : ('y1' !== l && 'y2' !== l) || (s[l] += this.offsetY - c);
        if (
          ((n = 'id="SVGID_' + this.id + '" gradientUnits="userSpaceOnUse"'),
          this.gradientTransform &&
            (n +=
              ' gradientTransform="matrix(' +
              this.gradientTransform.join(' ') +
              ')" '),
          'linear' === this.type
            ? (r = [
                '<linearGradient ',
                n,
                ' x1="',
                s.x1,
                '" y1="',
                s.y1,
                '" x2="',
                s.x2,
                '" y2="',
                s.y2,
                '">\n',
              ])
            : 'radial' === this.type &&
              (r = [
                '<radialGradient ',
                n,
                ' cx="',
                a ? s.x1 : s.x2,
                '" cy="',
                a ? s.y1 : s.y2,
                '" r="',
                a ? s.r1 : s.r2,
                '" fx="',
                a ? s.x2 : s.x1,
                '" fy="',
                a ? s.y2 : s.y1,
                '">\n',
              ]),
          'radial' === this.type)
        ) {
          if (a)
            for ((o = o.concat()).reverse(), e = 0, i = o.length; e < i; e++)
              o[e].offset = 1 - o[e].offset;
          var u = Math.min(s.r1, s.r2);
          if (0 < u) {
            var f = u / Math.max(s.r1, s.r2);
            for (e = 0, i = o.length; e < i; e++)
              o[e].offset += f * (1 - o[e].offset);
          }
        }
        for (e = 0, i = o.length; e < i; e++) {
          var d = o[e];
          r.push(
            '<stop ',
            'offset="',
            100 * d.offset + '%',
            '" style="stop-color:',
            d.color,
            void 0 !== d.opacity ? ';stop-opacity: ' + d.opacity : ';',
            '"/>\n'
          );
        }
        return (
          r.push(
            'linear' === this.type
              ? '</linearGradient>\n'
              : '</radialGradient>\n'
          ),
          r.join('')
        );
      },
      toLive: function(t) {
        var e,
          i,
          r,
          n = fabric.util.object.clone(this.coords);
        if (this.type) {
          for (
            'linear' === this.type
              ? (e = t.createLinearGradient(n.x1, n.y1, n.x2, n.y2))
              : 'radial' === this.type &&
                (e = t.createRadialGradient(
                  n.x1,
                  n.y1,
                  n.r1,
                  n.x2,
                  n.y2,
                  n.r2
                )),
              i = 0,
              r = this.colorStops.length;
            i < r;
            i++
          ) {
            var s = this.colorStops[i].color,
              o = this.colorStops[i].opacity,
              a = this.colorStops[i].offset;
            void 0 !== o && (s = new fabric.Color(s).setAlpha(o).toRgba()),
              e.addColorStop(a, s);
          }
          return e;
        }
      },
    })),
      fabric.util.object.extend(fabric.Gradient, {
        fromElement: function(t, e) {
          var i,
            r,
            n,
            s,
            o,
            a,
            h = t.getElementsByTagName('stop'),
            c = t.getAttribute('gradientUnits') || 'objectBoundingBox',
            l = t.getAttribute('gradientTransform'),
            u = [];
          for (
            'linear' ===
            (i =
              'linearGradient' === t.nodeName || 'LINEARGRADIENT' === t.nodeName
                ? 'linear'
                : 'radial')
              ? (r = {
                  x1: (a = t).getAttribute('x1') || 0,
                  y1: a.getAttribute('y1') || 0,
                  x2: a.getAttribute('x2') || '100%',
                  y2: a.getAttribute('y2') || 0,
                })
              : 'radial' === i &&
                (r = {
                  x1:
                    (o = t).getAttribute('fx') || o.getAttribute('cx') || '50%',
                  y1: o.getAttribute('fy') || o.getAttribute('cy') || '50%',
                  r1: 0,
                  x2: o.getAttribute('cx') || '50%',
                  y2: o.getAttribute('cy') || '50%',
                  r2: o.getAttribute('r') || '50%',
                }),
              s = h.length;
            s--;

          )
            u.push(d(h[s]));
          n = p(e, r, c);
          var f = new fabric.Gradient({
            type: i,
            coords: r,
            colorStops: u,
            offsetX: -e.left,
            offsetY: -e.top,
          });
          return (
            (l || '' !== n) &&
              (f.gradientTransform = fabric.parseTransformAttribute(
                (l || '') + n
              )),
            f
          );
        },
        forObject: function(t, e) {
          return (
            e || (e = {}),
            p(t, e.coords, 'userSpaceOnUse'),
            new fabric.Gradient(e)
          );
        },
      });
  })(),
  (function() {
    'use strict';
    var n = fabric.util.toFixed;
    fabric.Pattern = fabric.util.createClass({
      repeat: 'repeat',
      offsetX: 0,
      offsetY: 0,
      crossOrigin: '',
      patternTransform: null,
      initialize: function(t, e) {
        if (
          (t || (t = {}),
          (this.id = fabric.Object.__uid++),
          this.setOptions(t),
          !t.source || (t.source && 'string' != typeof t.source))
        )
          e && e(this);
        else if (void 0 !== fabric.util.getFunctionBody(t.source))
          (this.source = new Function(fabric.util.getFunctionBody(t.source))),
            e && e(this);
        else {
          var i = this;
          (this.source = fabric.util.createImage()),
            fabric.util.loadImage(
              t.source,
              function(t) {
                (i.source = t), e && e(i);
              },
              null,
              this.crossOrigin
            );
        }
      },
      toObject: function(t) {
        var e,
          i,
          r = fabric.Object.NUM_FRACTION_DIGITS;
        return (
          'function' == typeof this.source
            ? (e = String(this.source))
            : 'string' == typeof this.source.src
            ? (e = this.source.src)
            : 'object' == typeof this.source &&
              this.source.toDataURL &&
              (e = this.source.toDataURL()),
          (i = {
            type: 'pattern',
            source: e,
            repeat: this.repeat,
            crossOrigin: this.crossOrigin,
            offsetX: n(this.offsetX, r),
            offsetY: n(this.offsetY, r),
            patternTransform: this.patternTransform
              ? this.patternTransform.concat()
              : null,
          }),
          fabric.util.populateWithProperties(this, i, t),
          i
        );
      },
      toSVG: function(t) {
        var e = 'function' == typeof this.source ? this.source() : this.source,
          i = e.width / t.width,
          r = e.height / t.height,
          n = this.offsetX / t.width,
          s = this.offsetY / t.height,
          o = '';
        return (
          ('repeat-x' !== this.repeat && 'no-repeat' !== this.repeat) ||
            ((r = 1), s && (r += Math.abs(s))),
          ('repeat-y' !== this.repeat && 'no-repeat' !== this.repeat) ||
            ((i = 1), n && (i += Math.abs(n))),
          e.src ? (o = e.src) : e.toDataURL && (o = e.toDataURL()),
          '<pattern id="SVGID_' +
            this.id +
            '" x="' +
            n +
            '" y="' +
            s +
            '" width="' +
            i +
            '" height="' +
            r +
            '">\n<image x="0" y="0" width="' +
            e.width +
            '" height="' +
            e.height +
            '" xlink:href="' +
            o +
            '"></image>\n</pattern>\n'
        );
      },
      setOptions: function(t) {
        for (var e in t) this[e] = t[e];
      },
      toLive: function(t) {
        var e = 'function' == typeof this.source ? this.source() : this.source;
        if (!e) return '';
        if (void 0 !== e.src) {
          if (!e.complete) return '';
          if (0 === e.naturalWidth || 0 === e.naturalHeight) return '';
        }
        return t.createPattern(e, this.repeat);
      },
    });
  })(),
  (function(t) {
    'use strict';
    var o = t.fabric || (t.fabric = {}),
      a = o.util.toFixed;
    o.Shadow
      ? o.warn('fabric.Shadow is already defined.')
      : ((o.Shadow = o.util.createClass({
          color: 'rgb(0,0,0)',
          blur: 0,
          offsetX: 0,
          offsetY: 0,
          affectStroke: !1,
          includeDefaultValues: !0,
          initialize: function(t) {
            for (var e in ('string' == typeof t && (t = this._parseShadow(t)),
            t))
              this[e] = t[e];
            this.id = o.Object.__uid++;
          },
          _parseShadow: function(t) {
            var e = t.trim(),
              i = o.Shadow.reOffsetsAndBlur.exec(e) || [];
            return {
              color: (
                e.replace(o.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)'
              ).trim(),
              offsetX: parseInt(i[1], 10) || 0,
              offsetY: parseInt(i[2], 10) || 0,
              blur: parseInt(i[3], 10) || 0,
            };
          },
          toString: function() {
            return [this.offsetX, this.offsetY, this.blur, this.color].join(
              'px '
            );
          },
          toSVG: function(t) {
            var e = 40,
              i = 40,
              r = o.Object.NUM_FRACTION_DIGITS,
              n = o.util.rotateVector(
                { x: this.offsetX, y: this.offsetY },
                o.util.degreesToRadians(-t.angle)
              ),
              s = new o.Color(this.color);
            return (
              t.width &&
                t.height &&
                ((e = 100 * a((Math.abs(n.x) + this.blur) / t.width, r) + 20),
                (i = 100 * a((Math.abs(n.y) + this.blur) / t.height, r) + 20)),
              t.flipX && (n.x *= -1),
              t.flipY && (n.y *= -1),
              '<filter id="SVGID_' +
                this.id +
                '" y="-' +
                i +
                '%" height="' +
                (100 + 2 * i) +
                '%" x="-' +
                e +
                '%" width="' +
                (100 + 2 * e) +
                '%" >\n\t<feGaussianBlur in="SourceAlpha" stdDeviation="' +
                a(this.blur ? this.blur / 2 : 0, r) +
                '"></feGaussianBlur>\n\t<feOffset dx="' +
                a(n.x, r) +
                '" dy="' +
                a(n.y, r) +
                '" result="oBlur" ></feOffset>\n\t<feFlood flood-color="' +
                s.toRgb() +
                '" flood-opacity="' +
                s.getAlpha() +
                '"/>\n\t<feComposite in2="oBlur" operator="in" />\n\t<feMerge>\n\t\t<feMergeNode></feMergeNode>\n\t\t<feMergeNode in="SourceGraphic"></feMergeNode>\n\t</feMerge>\n</filter>\n'
            );
          },
          toObject: function() {
            if (this.includeDefaultValues)
              return {
                color: this.color,
                blur: this.blur,
                offsetX: this.offsetX,
                offsetY: this.offsetY,
                affectStroke: this.affectStroke,
              };
            var e = {},
              i = o.Shadow.prototype;
            return (
              ['color', 'blur', 'offsetX', 'offsetY', 'affectStroke'].forEach(
                function(t) {
                  this[t] !== i[t] && (e[t] = this[t]);
                },
                this
              ),
              e
            );
          },
        })),
        (o.Shadow.reOffsetsAndBlur = /(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/));
  })('undefined' != typeof exports ? exports : this),
  (function() {
    'use strict';
    if (fabric.StaticCanvas)
      fabric.warn('fabric.StaticCanvas is already defined.');
    else {
      var n = fabric.util.object.extend,
        t = fabric.util.getElementOffset,
        c = fabric.util.removeFromArray,
        a = fabric.util.toFixed,
        s = fabric.util.transformPoint,
        o = fabric.util.invertTransform,
        i = fabric.util.getNodeCanvas,
        r = fabric.util.createCanvasElement,
        e = new Error('Could not initialize `canvas` element');
      (fabric.StaticCanvas = fabric.util.createClass(fabric.CommonMethods, {
        initialize: function(t, e) {
          e || (e = {}),
            (this.renderAndResetBound = this.renderAndReset.bind(this)),
            (this.requestRenderAllBound = this.requestRenderAll.bind(this)),
            this._initStatic(t, e);
        },
        backgroundColor: '',
        backgroundImage: null,
        overlayColor: '',
        overlayImage: null,
        includeDefaultValues: !0,
        stateful: !1,
        renderOnAddRemove: !0,
        clipTo: null,
        controlsAboveOverlay: !1,
        allowTouchScrolling: !1,
        imageSmoothingEnabled: !0,
        viewportTransform: fabric.iMatrix.concat(),
        backgroundVpt: !0,
        overlayVpt: !0,
        onBeforeScaleRotate: function() {},
        enableRetinaScaling: !0,
        vptCoords: {},
        skipOffscreen: !0,
        clipPath: void 0,
        _initStatic: function(t, e) {
          var i = this.requestRenderAllBound;
          (this._objects = []),
            this._createLowerCanvas(t),
            this._initOptions(e),
            this._setImageSmoothing(),
            this.interactive || this._initRetinaScaling(),
            e.overlayImage && this.setOverlayImage(e.overlayImage, i),
            e.backgroundImage && this.setBackgroundImage(e.backgroundImage, i),
            e.backgroundColor && this.setBackgroundColor(e.backgroundColor, i),
            e.overlayColor && this.setOverlayColor(e.overlayColor, i),
            this.calcOffset();
        },
        _isRetinaScaling: function() {
          return 1 !== fabric.devicePixelRatio && this.enableRetinaScaling;
        },
        getRetinaScaling: function() {
          return this._isRetinaScaling() ? fabric.devicePixelRatio : 1;
        },
        _initRetinaScaling: function() {
          this._isRetinaScaling() &&
            (this.lowerCanvasEl.setAttribute(
              'width',
              this.width * fabric.devicePixelRatio
            ),
            this.lowerCanvasEl.setAttribute(
              'height',
              this.height * fabric.devicePixelRatio
            ),
            this.contextContainer.scale(
              fabric.devicePixelRatio,
              fabric.devicePixelRatio
            ));
        },
        calcOffset: function() {
          return (this._offset = t(this.lowerCanvasEl)), this;
        },
        setOverlayImage: function(t, e, i) {
          return this.__setBgOverlayImage('overlayImage', t, e, i);
        },
        setBackgroundImage: function(t, e, i) {
          return this.__setBgOverlayImage('backgroundImage', t, e, i);
        },
        setOverlayColor: function(t, e) {
          return this.__setBgOverlayColor('overlayColor', t, e);
        },
        setBackgroundColor: function(t, e) {
          return this.__setBgOverlayColor('backgroundColor', t, e);
        },
        _setImageSmoothing: function() {
          var t = this.getContext();
          (t.imageSmoothingEnabled =
            t.imageSmoothingEnabled ||
            t.webkitImageSmoothingEnabled ||
            t.mozImageSmoothingEnabled ||
            t.msImageSmoothingEnabled ||
            t.oImageSmoothingEnabled),
            (t.imageSmoothingEnabled = this.imageSmoothingEnabled);
        },
        __setBgOverlayImage: function(i, t, r, n) {
          return (
            'string' == typeof t
              ? fabric.util.loadImage(
                  t,
                  function(t) {
                    if (t) {
                      var e = new fabric.Image(t, n);
                      (this[i] = e).canvas = this;
                    }
                    r && r(t);
                  },
                  this,
                  n && n.crossOrigin
                )
              : (n && t.setOptions(n),
                (this[i] = t) && (t.canvas = this),
                r && r(t)),
            this
          );
        },
        __setBgOverlayColor: function(t, e, i) {
          return (
            (this[t] = e),
            this._initGradient(e, t),
            this._initPattern(e, t, i),
            this
          );
        },
        _createCanvasElement: function() {
          var t = r();
          if (!t) throw e;
          if ((t.style || (t.style = {}), void 0 === t.getContext)) throw e;
          return t;
        },
        _initOptions: function(t) {
          var e = this.lowerCanvasEl;
          this._setOptions(t),
            (this.width = this.width || parseInt(e.width, 10) || 0),
            (this.height = this.height || parseInt(e.height, 10) || 0),
            this.lowerCanvasEl.style &&
              ((e.width = this.width),
              (e.height = this.height),
              (e.style.width = this.width + 'px'),
              (e.style.height = this.height + 'px'),
              (this.viewportTransform = this.viewportTransform.slice()));
        },
        _createLowerCanvas: function(t) {
          t && t.getContext
            ? (this.lowerCanvasEl = t)
            : (this.lowerCanvasEl =
                fabric.util.getById(t) || this._createCanvasElement()),
            fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas'),
            this.interactive && this._applyCanvasStyle(this.lowerCanvasEl),
            (this.contextContainer = this.lowerCanvasEl.getContext('2d'));
        },
        getWidth: function() {
          return this.width;
        },
        getHeight: function() {
          return this.height;
        },
        setWidth: function(t, e) {
          return this.setDimensions({ width: t }, e);
        },
        setHeight: function(t, e) {
          return this.setDimensions({ height: t }, e);
        },
        setDimensions: function(t, e) {
          var i;
          for (var r in ((e = e || {}), t))
            (i = t[r]),
              e.cssOnly ||
                (this._setBackstoreDimension(r, t[r]),
                (i += 'px'),
                (this.hasLostContext = !0)),
              e.backstoreOnly || this._setCssDimension(r, i);
          return (
            this._isCurrentlyDrawing &&
              this.freeDrawingBrush &&
              this.freeDrawingBrush._setBrushStyles(),
            this._initRetinaScaling(),
            this._setImageSmoothing(),
            this.calcOffset(),
            e.cssOnly || this.requestRenderAll(),
            this
          );
        },
        _setBackstoreDimension: function(t, e) {
          return (
            (this.lowerCanvasEl[t] = e),
            this.upperCanvasEl && (this.upperCanvasEl[t] = e),
            this.cacheCanvasEl && (this.cacheCanvasEl[t] = e),
            (this[t] = e),
            this
          );
        },
        _setCssDimension: function(t, e) {
          return (
            (this.lowerCanvasEl.style[t] = e),
            this.upperCanvasEl && (this.upperCanvasEl.style[t] = e),
            this.wrapperEl && (this.wrapperEl.style[t] = e),
            this
          );
        },
        getZoom: function() {
          return this.viewportTransform[0];
        },
        setViewportTransform: function(t) {
          var e,
            i,
            r,
            n = this._activeObject;
          for (
            this.viewportTransform = t, i = 0, r = this._objects.length;
            i < r;
            i++
          )
            (e = this._objects[i]).group || e.setCoords(!1, !0);
          return (
            n && 'activeSelection' === n.type && n.setCoords(!1, !0),
            this.calcViewportBoundaries(),
            this.renderOnAddRemove && this.requestRenderAll(),
            this
          );
        },
        zoomToPoint: function(t, e) {
          var i = t,
            r = this.viewportTransform.slice(0);
          (t = s(t, o(this.viewportTransform))), (r[0] = e), (r[3] = e);
          var n = s(t, r);
          return (
            (r[4] += i.x - n.x),
            (r[5] += i.y - n.y),
            this.setViewportTransform(r)
          );
        },
        setZoom: function(t) {
          return this.zoomToPoint(new fabric.Point(0, 0), t), this;
        },
        absolutePan: function(t) {
          var e = this.viewportTransform.slice(0);
          return (e[4] = -t.x), (e[5] = -t.y), this.setViewportTransform(e);
        },
        relativePan: function(t) {
          return this.absolutePan(
            new fabric.Point(
              -t.x - this.viewportTransform[4],
              -t.y - this.viewportTransform[5]
            )
          );
        },
        getElement: function() {
          return this.lowerCanvasEl;
        },
        _onObjectAdded: function(t) {
          this.stateful && t.setupState(),
            t._set('canvas', this),
            t.setCoords(),
            this.fire('object:added', { target: t }),
            t.fire('added');
        },
        _onObjectRemoved: function(t) {
          this.fire('object:removed', { target: t }),
            t.fire('removed'),
            delete t.canvas;
        },
        clearContext: function(t) {
          return t.clearRect(0, 0, this.width, this.height), this;
        },
        getContext: function() {
          return this.contextContainer;
        },
        clear: function() {
          return (
            (this._objects.length = 0),
            (this.backgroundImage = null),
            (this.overlayImage = null),
            (this.backgroundColor = ''),
            (this.overlayColor = ''),
            this._hasITextHandlers &&
              (this.off('mouse:up', this._mouseUpITextHandler),
              (this._iTextInstances = null),
              (this._hasITextHandlers = !1)),
            this.clearContext(this.contextContainer),
            this.fire('canvas:cleared'),
            this.renderOnAddRemove && this.requestRenderAll(),
            this
          );
        },
        renderAll: function() {
          var t = this.contextContainer;
          return this.renderCanvas(t, this._objects), this;
        },
        renderAndReset: function() {
          (this.isRendering = 0), this.renderAll();
        },
        requestRenderAll: function() {
          return (
            this.isRendering ||
              (this.isRendering = fabric.util.requestAnimFrame(
                this.renderAndResetBound
              )),
            this
          );
        },
        calcViewportBoundaries: function() {
          var t = {},
            e = this.width,
            i = this.height,
            r = o(this.viewportTransform);
          return (
            (t.tl = s({ x: 0, y: 0 }, r)),
            (t.br = s({ x: e, y: i }, r)),
            (t.tr = new fabric.Point(t.br.x, t.tl.y)),
            (t.bl = new fabric.Point(t.tl.x, t.br.y)),
            (this.vptCoords = t)
          );
        },
        cancelRequestedRender: function() {
          this.isRendering &&
            (fabric.util.cancelAnimFrame(this.isRendering),
            (this.isRendering = 0));
        },
        renderCanvas: function(t, e) {
          var i = this.viewportTransform,
            r = this.clipPath;
          this.cancelRequestedRender(),
            this.calcViewportBoundaries(),
            this.clearContext(t),
            this.fire('before:render', { ctx: t }),
            this.clipTo && fabric.util.clipContext(this, t),
            this._renderBackground(t),
            t.save(),
            t.transform(i[0], i[1], i[2], i[3], i[4], i[5]),
            this._renderObjects(t, e),
            t.restore(),
            !this.controlsAboveOverlay &&
              this.interactive &&
              this.drawControls(t),
            this.clipTo && t.restore(),
            r &&
              ((r.canvas = this),
              r.shouldCache(),
              (r._transformDone = !0),
              r.renderCache({ forClipping: !0 }),
              this.drawClipPathOnCanvas(t)),
            this._renderOverlay(t),
            this.controlsAboveOverlay &&
              this.interactive &&
              this.drawControls(t),
            this.fire('after:render', { ctx: t });
        },
        drawClipPathOnCanvas: function(t) {
          var e = this.viewportTransform,
            i = this.clipPath;
          t.save(),
            t.transform(e[0], e[1], e[2], e[3], e[4], e[5]),
            (t.globalCompositeOperation = 'destination-in'),
            i.transform(t),
            t.scale(1 / i.zoomX, 1 / i.zoomY),
            t.drawImage(
              i._cacheCanvas,
              -i.cacheTranslationX,
              -i.cacheTranslationY
            ),
            t.restore();
        },
        _renderObjects: function(t, e) {
          var i, r;
          for (i = 0, r = e.length; i < r; ++i) e[i] && e[i].render(t);
        },
        _renderBackgroundOrOverlay: function(t, e) {
          var i,
            r = this[e + 'Color'];
          r &&
            ((t.fillStyle = r.toLive ? r.toLive(t, this) : r),
            t.fillRect(
              r.offsetX || 0,
              r.offsetY || 0,
              this.width,
              this.height
            )),
            (r = this[e + 'Image']) &&
              (this[e + 'Vpt'] &&
                ((i = this.viewportTransform),
                t.save(),
                t.transform(i[0], i[1], i[2], i[3], i[4], i[5])),
              r.render(t),
              this[e + 'Vpt'] && t.restore());
        },
        _renderBackground: function(t) {
          this._renderBackgroundOrOverlay(t, 'background');
        },
        _renderOverlay: function(t) {
          this._renderBackgroundOrOverlay(t, 'overlay');
        },
        getCenter: function() {
          return { top: this.height / 2, left: this.width / 2 };
        },
        centerObjectH: function(t) {
          return this._centerObject(
            t,
            new fabric.Point(this.getCenter().left, t.getCenterPoint().y)
          );
        },
        centerObjectV: function(t) {
          return this._centerObject(
            t,
            new fabric.Point(t.getCenterPoint().x, this.getCenter().top)
          );
        },
        centerObject: function(t) {
          var e = this.getCenter();
          return this._centerObject(t, new fabric.Point(e.left, e.top));
        },
        viewportCenterObject: function(t) {
          var e = this.getVpCenter();
          return this._centerObject(t, e);
        },
        viewportCenterObjectH: function(t) {
          var e = this.getVpCenter();
          return (
            this._centerObject(t, new fabric.Point(e.x, t.getCenterPoint().y)),
            this
          );
        },
        viewportCenterObjectV: function(t) {
          var e = this.getVpCenter();
          return this._centerObject(
            t,
            new fabric.Point(t.getCenterPoint().x, e.y)
          );
        },
        getVpCenter: function() {
          var t = this.getCenter(),
            e = o(this.viewportTransform);
          return s({ x: t.left, y: t.top }, e);
        },
        _centerObject: function(t, e) {
          return (
            t.setPositionByOrigin(e, 'center', 'center'),
            t.setCoords(),
            this.renderOnAddRemove && this.requestRenderAll(),
            this
          );
        },
        toDatalessJSON: function(t) {
          return this.toDatalessObject(t);
        },
        toObject: function(t) {
          return this._toObjectMethod('toObject', t);
        },
        toDatalessObject: function(t) {
          return this._toObjectMethod('toDatalessObject', t);
        },
        _toObjectMethod: function(t, e) {
          var i = this.clipPath,
            r = { version: fabric.version, objects: this._toObjects(t, e) };
          return (
            i && (i = i.toObject(e)),
            n(r, this.__serializeBgOverlay(t, e)),
            fabric.util.populateWithProperties(this, r, e),
            r
          );
        },
        _toObjects: function(e, i) {
          return this._objects
            .filter(function(t) {
              return !t.excludeFromExport;
            })
            .map(function(t) {
              return this._toObject(t, e, i);
            }, this);
        },
        _toObject: function(t, e, i) {
          var r;
          this.includeDefaultValues ||
            ((r = t.includeDefaultValues), (t.includeDefaultValues = !1));
          var n = t[e](i);
          return this.includeDefaultValues || (t.includeDefaultValues = r), n;
        },
        __serializeBgOverlay: function(t, e) {
          var i = {},
            r = this.backgroundImage,
            n = this.overlayImage;
          return (
            this.backgroundColor &&
              (i.background = this.backgroundColor.toObject
                ? this.backgroundColor.toObject(e)
                : this.backgroundColor),
            this.overlayColor &&
              (i.overlay = this.overlayColor.toObject
                ? this.overlayColor.toObject(e)
                : this.overlayColor),
            r &&
              !r.excludeFromExport &&
              (i.backgroundImage = this._toObject(r, t, e)),
            n &&
              !n.excludeFromExport &&
              (i.overlayImage = this._toObject(n, t, e)),
            i
          );
        },
        svgViewportTransformation: !0,
        toSVG: function(t, e) {
          t || (t = {}), (t.reviver = e);
          var i = [];
          return (
            this._setSVGPreamble(i, t),
            this._setSVGHeader(i, t),
            this.clipPath &&
              i.push(
                '<g clip-path="url(#' + this.clipPath.clipPathId + ')" >\n'
              ),
            this._setSVGBgOverlayColor(i, 'backgroundColor'),
            this._setSVGBgOverlayImage(i, 'backgroundImage', e),
            this._setSVGObjects(i, e),
            this.clipPath && i.push('</g>\n'),
            this._setSVGBgOverlayColor(i, 'overlayColor'),
            this._setSVGBgOverlayImage(i, 'overlayImage', e),
            i.push('</svg>'),
            i.join('')
          );
        },
        _setSVGPreamble: function(t, e) {
          e.suppressPreamble ||
            t.push(
              '<?xml version="1.0" encoding="',
              e.encoding || 'UTF-8',
              '" standalone="no" ?>\n',
              '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ',
              '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n'
            );
        },
        _setSVGHeader: function(t, e) {
          var i,
            r = e.width || this.width,
            n = e.height || this.height,
            s = 'viewBox="0 0 ' + this.width + ' ' + this.height + '" ',
            o = fabric.Object.NUM_FRACTION_DIGITS;
          e.viewBox
            ? (s =
                'viewBox="' +
                e.viewBox.x +
                ' ' +
                e.viewBox.y +
                ' ' +
                e.viewBox.width +
                ' ' +
                e.viewBox.height +
                '" ')
            : this.svgViewportTransformation &&
              ((i = this.viewportTransform),
              (s =
                'viewBox="' +
                a(-i[4] / i[0], o) +
                ' ' +
                a(-i[5] / i[3], o) +
                ' ' +
                a(this.width / i[0], o) +
                ' ' +
                a(this.height / i[3], o) +
                '" ')),
            t.push(
              '<svg ',
              'xmlns="http://www.w3.org/2000/svg" ',
              'xmlns:xlink="http://www.w3.org/1999/xlink" ',
              'version="1.1" ',
              'width="',
              r,
              '" ',
              'height="',
              n,
              '" ',
              s,
              'xml:space="preserve">\n',
              '<desc>Created with Fabric.js ',
              fabric.version,
              '</desc>\n',
              '<defs>\n',
              this.createSVGFontFacesMarkup(),
              this.createSVGRefElementsMarkup(),
              this.createSVGClipPathMarkup(e),
              '</defs>\n'
            );
        },
        createSVGClipPathMarkup: function(t) {
          var e = this.clipPath;
          return e
            ? ((e.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++),
              '<clipPath id="' +
                e.clipPathId +
                '" >\n' +
                this.clipPath.toClipPathSVG(t.reviver) +
                '</clipPath>\n')
            : '';
        },
        createSVGRefElementsMarkup: function() {
          var i = this;
          return ['backgroundColor', 'overlayColor']
            .map(function(t) {
              var e = i[t];
              if (e && e.toLive) return e.toSVG(i, !1);
            })
            .join('');
        },
        createSVGFontFacesMarkup: function() {
          var t,
            e,
            i,
            r,
            n,
            s,
            o,
            a,
            h = '',
            c = {},
            l = fabric.fontPaths,
            u = this._objects;
          for (o = 0, a = u.length; o < a; o++)
            if (
              ((e = (t = u[o]).fontFamily),
              -1 !== t.type.indexOf('text') &&
                !c[e] &&
                l[e] &&
                ((c[e] = !0), t.styles))
            )
              for (n in (i = t.styles))
                for (s in (r = i[n]))
                  !c[(e = r[s].fontFamily)] && l[e] && (c[e] = !0);
          for (var f in c)
            h += [
              '\t\t@font-face {\n',
              "\t\t\tfont-family: '",
              f,
              "';\n",
              "\t\t\tsrc: url('",
              l[f],
              "');\n",
              '\t\t}\n',
            ].join('');
          return (
            h &&
              (h = [
                '\t<style type="text/css">',
                '<![CDATA[\n',
                h,
                ']]>',
                '</style>\n',
              ].join('')),
            h
          );
        },
        _setSVGObjects: function(t, e) {
          var i,
            r,
            n,
            s = this._objects;
          for (r = 0, n = s.length; r < n; r++)
            (i = s[r]).excludeFromExport || this._setSVGObject(t, i, e);
        },
        _setSVGObject: function(t, e, i) {
          t.push(e.toSVG(i));
        },
        _setSVGBgOverlayImage: function(t, e, i) {
          this[e] &&
            !this[e].excludeFromExport &&
            this[e].toSVG &&
            t.push(this[e].toSVG(i));
        },
        _setSVGBgOverlayColor: function(t, e) {
          var i = this[e],
            r = this.viewportTransform,
            n = this.width / r[0],
            s = this.height / r[3];
          if (i)
            if (i.toLive) {
              var o = i.repeat;
              t.push(
                '<rect transform="translate(',
                n / 2,
                ',',
                s / 2,
                ')"',
                ' x="',
                i.offsetX - n / 2,
                '" y="',
                i.offsetY - s / 2,
                '" ',
                'width="',
                'repeat-y' === o || 'no-repeat' === o ? i.source.width : n,
                '" height="',
                'repeat-x' === o || 'no-repeat' === o ? i.source.height : s,
                '" fill="url(#SVGID_' + i.id + ')"',
                '></rect>\n'
              );
            } else
              t.push(
                '<rect x="0" y="0" width="100%" height="100%" ',
                'fill="',
                this[e],
                '"',
                '></rect>\n'
              );
        },
        sendToBack: function(t) {
          if (!t) return this;
          var e,
            i,
            r,
            n = this._activeObject;
          if (t === n && 'activeSelection' === t.type)
            for (e = (r = n._objects).length; e--; )
              (i = r[e]), c(this._objects, i), this._objects.unshift(i);
          else c(this._objects, t), this._objects.unshift(t);
          return this.renderOnAddRemove && this.requestRenderAll(), this;
        },
        bringToFront: function(t) {
          if (!t) return this;
          var e,
            i,
            r,
            n = this._activeObject;
          if (t === n && 'activeSelection' === t.type)
            for (r = n._objects, e = 0; e < r.length; e++)
              (i = r[e]), c(this._objects, i), this._objects.push(i);
          else c(this._objects, t), this._objects.push(t);
          return this.renderOnAddRemove && this.requestRenderAll(), this;
        },
        sendBackwards: function(t, e) {
          if (!t) return this;
          var i,
            r,
            n,
            s,
            o,
            a = this._activeObject,
            h = 0;
          if (t === a && 'activeSelection' === t.type)
            for (o = a._objects, i = 0; i < o.length; i++)
              (r = o[i]),
                0 + h < (n = this._objects.indexOf(r)) &&
                  ((s = n - 1),
                  c(this._objects, r),
                  this._objects.splice(s, 0, r)),
                h++;
          else
            0 !== (n = this._objects.indexOf(t)) &&
              ((s = this._findNewLowerIndex(t, n, e)),
              c(this._objects, t),
              this._objects.splice(s, 0, t));
          return this.renderOnAddRemove && this.requestRenderAll(), this;
        },
        _findNewLowerIndex: function(t, e, i) {
          var r, n;
          if (i)
            for (n = (r = e) - 1; 0 <= n; --n) {
              if (
                t.intersectsWithObject(this._objects[n]) ||
                t.isContainedWithinObject(this._objects[n]) ||
                this._objects[n].isContainedWithinObject(t)
              ) {
                r = n;
                break;
              }
            }
          else r = e - 1;
          return r;
        },
        bringForward: function(t, e) {
          if (!t) return this;
          var i,
            r,
            n,
            s,
            o,
            a = this._activeObject,
            h = 0;
          if (t === a && 'activeSelection' === t.type)
            for (i = (o = a._objects).length; i--; )
              (r = o[i]),
                (n = this._objects.indexOf(r)) < this._objects.length - 1 - h &&
                  ((s = n + 1),
                  c(this._objects, r),
                  this._objects.splice(s, 0, r)),
                h++;
          else
            (n = this._objects.indexOf(t)) !== this._objects.length - 1 &&
              ((s = this._findNewUpperIndex(t, n, e)),
              c(this._objects, t),
              this._objects.splice(s, 0, t));
          return this.renderOnAddRemove && this.requestRenderAll(), this;
        },
        _findNewUpperIndex: function(t, e, i) {
          var r, n, s;
          if (i)
            for (n = (r = e) + 1, s = this._objects.length; n < s; ++n) {
              if (
                t.intersectsWithObject(this._objects[n]) ||
                t.isContainedWithinObject(this._objects[n]) ||
                this._objects[n].isContainedWithinObject(t)
              ) {
                r = n;
                break;
              }
            }
          else r = e + 1;
          return r;
        },
        moveTo: function(t, e) {
          return (
            c(this._objects, t),
            this._objects.splice(e, 0, t),
            this.renderOnAddRemove && this.requestRenderAll()
          );
        },
        dispose: function() {
          return (
            this.isRendering &&
              (fabric.util.cancelAnimFrame(this.isRendering),
              (this.isRendering = 0)),
            this.forEachObject(function(t) {
              t.dispose && t.dispose();
            }),
            (this._objects = []),
            this.backgroundImage &&
              this.backgroundImage.dispose &&
              this.backgroundImage.dispose(),
            (this.backgroundImage = null),
            this.overlayImage &&
              this.overlayImage.dispose &&
              this.overlayImage.dispose(),
            (this.overlayImage = null),
            (this._iTextInstances = null),
            (this.contextContainer = null),
            fabric.util.cleanUpJsdomNode(this.lowerCanvasEl),
            (this.lowerCanvasEl = void 0),
            this
          );
        },
        toString: function() {
          return (
            '#<fabric.Canvas (' +
            this.complexity() +
            '): { objects: ' +
            this._objects.length +
            ' }>'
          );
        },
      })),
        n(fabric.StaticCanvas.prototype, fabric.Observable),
        n(fabric.StaticCanvas.prototype, fabric.Collection),
        n(fabric.StaticCanvas.prototype, fabric.DataURLExporter),
        n(fabric.StaticCanvas, {
          EMPTY_JSON: '{"objects": [], "background": "white"}',
          supports: function(t) {
            var e = r();
            if (!e || !e.getContext) return null;
            var i = e.getContext('2d');
            if (!i) return null;
            switch (t) {
              case 'getImageData':
                return void 0 !== i.getImageData;
              case 'setLineDash':
                return void 0 !== i.setLineDash;
              case 'toDataURL':
                return void 0 !== e.toDataURL;
              case 'toDataURLWithQuality':
                try {
                  return e.toDataURL('image/jpeg', 0), !0;
                } catch (t) {}
                return !1;
              default:
                return null;
            }
          },
        }),
        (fabric.StaticCanvas.prototype.toJSON =
          fabric.StaticCanvas.prototype.toObject),
        fabric.isLikelyNode &&
          ((fabric.StaticCanvas.prototype.createPNGStream = function() {
            var t = i(this.lowerCanvasEl);
            return t && t.createPNGStream();
          }),
          (fabric.StaticCanvas.prototype.createJPEGStream = function(t) {
            var e = i(this.lowerCanvasEl);
            return e && e.createJPEGStream(t);
          }));
    }
  })(),
  (fabric.BaseBrush = fabric.util.createClass({
    color: 'rgb(0, 0, 0)',
    width: 1,
    shadow: null,
    strokeLineCap: 'round',
    strokeLineJoin: 'round',
    strokeMiterLimit: 10,
    strokeDashArray: null,
    setShadow: function(t) {
      return (this.shadow = new fabric.Shadow(t)), this;
    },
    _setBrushStyles: function() {
      var t = this.canvas.contextTop;
      (t.strokeStyle = this.color),
        (t.lineWidth = this.width),
        (t.lineCap = this.strokeLineCap),
        (t.miterLimit = this.strokeMiterLimit),
        (t.lineJoin = this.strokeLineJoin),
        fabric.StaticCanvas.supports('setLineDash') &&
          t.setLineDash(this.strokeDashArray || []);
    },
    _saveAndTransform: function(t) {
      var e = this.canvas.viewportTransform;
      t.save(), t.transform(e[0], e[1], e[2], e[3], e[4], e[5]);
    },
    _setShadow: function() {
      if (this.shadow) {
        var t = this.canvas.contextTop,
          e = this.canvas.getZoom();
        (t.shadowColor = this.shadow.color),
          (t.shadowBlur = this.shadow.blur * e),
          (t.shadowOffsetX = this.shadow.offsetX * e),
          (t.shadowOffsetY = this.shadow.offsetY * e);
      }
    },
    _resetShadow: function() {
      var t = this.canvas.contextTop;
      (t.shadowColor = ''),
        (t.shadowBlur = t.shadowOffsetX = t.shadowOffsetY = 0);
    },
  })),
  (fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, {
    initialize: function(t) {
      (this.canvas = t), (this._points = []);
    },
    _drawSegment: function(t, e, i) {
      var r = e.midPointFrom(i);
      return t.quadraticCurveTo(e.x, e.y, r.x, r.y), r;
    },
    onMouseDown: function(t) {
      this._prepareForDrawing(t), this._captureDrawingPath(t), this._render();
    },
    onMouseMove: function(t) {
      if (this._captureDrawingPath(t) && 1 < this._points.length)
        if (this.needsFullRender)
          this.canvas.clearContext(this.canvas.contextTop), this._render();
        else {
          var e = this._points,
            i = e.length,
            r = this.canvas.contextTop;
          this._saveAndTransform(r),
            this.oldEnd &&
              (r.beginPath(), r.moveTo(this.oldEnd.x, this.oldEnd.y)),
            (this.oldEnd = this._drawSegment(r, e[i - 2], e[i - 1], !0)),
            r.stroke(),
            r.restore();
        }
    },
    onMouseUp: function() {
      (this.oldEnd = void 0), this._finalizeAndAddPath();
    },
    _prepareForDrawing: function(t) {
      var e = new fabric.Point(t.x, t.y);
      this._reset(), this._addPoint(e), this.canvas.contextTop.moveTo(e.x, e.y);
    },
    _addPoint: function(t) {
      return !(
        (1 < this._points.length &&
          t.eq(this._points[this._points.length - 1])) ||
        (this._points.push(t), 0)
      );
    },
    _reset: function() {
      (this._points.length = 0), this._setBrushStyles();
      var t = new fabric.Color(this.color);
      (this.needsFullRender = t.getAlpha() < 1), this._setShadow();
    },
    _captureDrawingPath: function(t) {
      var e = new fabric.Point(t.x, t.y);
      return this._addPoint(e);
    },
    _render: function() {
      var t,
        e,
        i = this.canvas.contextTop,
        r = this._points[0],
        n = this._points[1];
      if (
        (this._saveAndTransform(i),
        i.beginPath(),
        2 === this._points.length && r.x === n.x && r.y === n.y)
      ) {
        var s = this.width / 1e3;
        (r = new fabric.Point(r.x, r.y)),
          (n = new fabric.Point(n.x, n.y)),
          (r.x -= s),
          (n.x += s);
      }
      for (i.moveTo(r.x, r.y), t = 1, e = this._points.length; t < e; t++)
        this._drawSegment(i, r, n),
          (r = this._points[t]),
          (n = this._points[t + 1]);
      i.lineTo(r.x, r.y), i.stroke(), i.restore();
    },
    convertPointsToSVGPath: function(t) {
      var e,
        i = [],
        r = this.width / 1e3,
        n = new fabric.Point(t[0].x, t[0].y),
        s = new fabric.Point(t[1].x, t[1].y),
        o = t.length,
        a = 1,
        h = 1,
        c = 2 < o;
      for (
        c &&
          ((a = t[2].x < s.x ? -1 : t[2].x === s.x ? 0 : 1),
          (h = t[2].y < s.y ? -1 : t[2].y === s.y ? 0 : 1)),
          i.push('M ', n.x - a * r, ' ', n.y - h * r, ' '),
          e = 1;
        e < o;
        e++
      ) {
        if (!n.eq(s)) {
          var l = n.midPointFrom(s);
          i.push('Q ', n.x, ' ', n.y, ' ', l.x, ' ', l.y, ' ');
        }
        (n = t[e]), e + 1 < t.length && (s = t[e + 1]);
      }
      return (
        c &&
          ((a = n.x > t[e - 2].x ? 1 : n.x === t[e - 2].x ? 0 : -1),
          (h = n.y > t[e - 2].y ? 1 : n.y === t[e - 2].y ? 0 : -1)),
        i.push('L ', n.x + a * r, ' ', n.y + h * r),
        i
      );
    },
    createPath: function(t) {
      var e = new fabric.Path(t, {
          fill: null,
          stroke: this.color,
          strokeWidth: this.width,
          strokeLineCap: this.strokeLineCap,
          strokeMiterLimit: this.strokeMiterLimit,
          strokeLineJoin: this.strokeLineJoin,
          strokeDashArray: this.strokeDashArray,
        }),
        i = new fabric.Point(e.left + e.width / 2, e.top + e.height / 2);
      return (
        (i = e.translateToGivenOrigin(
          i,
          'center',
          'center',
          e.originX,
          e.originY
        )),
        (e.top = i.y),
        (e.left = i.x),
        this.shadow &&
          ((this.shadow.affectStroke = !0), e.setShadow(this.shadow)),
        e
      );
    },
    _finalizeAndAddPath: function() {
      this.canvas.contextTop.closePath();
      var t = this.convertPointsToSVGPath(this._points).join('');
      if ('M 0 0 Q 0 0 0 0 L 0 0' !== t) {
        var e = this.createPath(t);
        this.canvas.clearContext(this.canvas.contextTop),
          this.canvas.add(e),
          this.canvas.renderAll(),
          e.setCoords(),
          this._resetShadow(),
          this.canvas.fire('path:created', { path: e });
      } else this.canvas.requestRenderAll();
    },
  })),
  (fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, {
    width: 10,
    initialize: function(t) {
      (this.canvas = t), (this.points = []);
    },
    drawDot: function(t) {
      var e = this.addPoint(t),
        i = this.canvas.contextTop;
      this._saveAndTransform(i),
        (i.fillStyle = e.fill),
        i.beginPath(),
        i.arc(e.x, e.y, e.radius, 0, 2 * Math.PI, !1),
        i.closePath(),
        i.fill(),
        i.restore();
    },
    onMouseDown: function(t) {
      (this.points.length = 0),
        this.canvas.clearContext(this.canvas.contextTop),
        this._setShadow(),
        this.drawDot(t);
    },
    _render: function() {
      var t,
        e,
        i,
        r = this.canvas.contextTop,
        n = this.points;
      for (this._saveAndTransform(r), t = 0, e = n.length; t < e; t++)
        (i = n[t]),
          (r.fillStyle = i.fill),
          r.beginPath(),
          r.arc(i.x, i.y, i.radius, 0, 2 * Math.PI, !1),
          r.closePath(),
          r.fill();
      r.restore();
    },
    onMouseMove: function(t) {
      this.drawDot(t);
    },
    onMouseUp: function() {
      var t,
        e,
        i = this.canvas.renderOnAddRemove;
      this.canvas.renderOnAddRemove = !1;
      var r = [];
      for (t = 0, e = this.points.length; t < e; t++) {
        var n = this.points[t],
          s = new fabric.Circle({
            radius: n.radius,
            left: n.x,
            top: n.y,
            originX: 'center',
            originY: 'center',
            fill: n.fill,
          });
        this.shadow && s.setShadow(this.shadow), r.push(s);
      }
      var o = new fabric.Group(r);
      (o.canvas = this.canvas),
        this.canvas.add(o),
        this.canvas.fire('path:created', { path: o }),
        this.canvas.clearContext(this.canvas.contextTop),
        this._resetShadow(),
        (this.canvas.renderOnAddRemove = i),
        this.canvas.requestRenderAll();
    },
    addPoint: function(t) {
      var e = new fabric.Point(t.x, t.y),
        i =
          fabric.util.getRandomInt(
            Math.max(0, this.width - 20),
            this.width + 20
          ) / 2,
        r = new fabric.Color(this.color)
          .setAlpha(fabric.util.getRandomInt(0, 100) / 100)
          .toRgba();
      return (e.radius = i), (e.fill = r), this.points.push(e), e;
    },
  })),
  (fabric.SprayBrush = fabric.util.createClass(fabric.BaseBrush, {
    width: 10,
    density: 20,
    dotWidth: 1,
    dotWidthVariance: 1,
    randomOpacity: !1,
    optimizeOverlapping: !0,
    initialize: function(t) {
      (this.canvas = t), (this.sprayChunks = []);
    },
    onMouseDown: function(t) {
      (this.sprayChunks.length = 0),
        this.canvas.clearContext(this.canvas.contextTop),
        this._setShadow(),
        this.addSprayChunk(t),
        this.render(this.sprayChunkPoints);
    },
    onMouseMove: function(t) {
      this.addSprayChunk(t), this.render(this.sprayChunkPoints);
    },
    onMouseUp: function() {
      var t = this.canvas.renderOnAddRemove;
      this.canvas.renderOnAddRemove = !1;
      for (var e = [], i = 0, r = this.sprayChunks.length; i < r; i++)
        for (var n = this.sprayChunks[i], s = 0, o = n.length; s < o; s++) {
          var a = new fabric.Rect({
            width: n[s].width,
            height: n[s].width,
            left: n[s].x + 1,
            top: n[s].y + 1,
            originX: 'center',
            originY: 'center',
            fill: this.color,
          });
          e.push(a);
        }
      this.optimizeOverlapping && (e = this._getOptimizedRects(e));
      var h = new fabric.Group(e);
      this.shadow && h.setShadow(this.shadow),
        this.canvas.add(h),
        this.canvas.fire('path:created', { path: h }),
        this.canvas.clearContext(this.canvas.contextTop),
        this._resetShadow(),
        (this.canvas.renderOnAddRemove = t),
        this.canvas.requestRenderAll();
    },
    _getOptimizedRects: function(t) {
      var e,
        i,
        r,
        n = {};
      for (i = 0, r = t.length; i < r; i++)
        n[(e = t[i].left + '' + t[i].top)] || (n[e] = t[i]);
      var s = [];
      for (e in n) s.push(n[e]);
      return s;
    },
    render: function(t) {
      var e,
        i,
        r = this.canvas.contextTop;
      for (
        r.fillStyle = this.color,
          this._saveAndTransform(r),
          e = 0,
          i = t.length;
        e < i;
        e++
      ) {
        var n = t[e];
        void 0 !== n.opacity && (r.globalAlpha = n.opacity),
          r.fillRect(n.x, n.y, n.width, n.width);
      }
      r.restore();
    },
    _render: function() {
      var t,
        e,
        i = this.canvas.contextTop;
      for (
        i.fillStyle = this.color,
          this._saveAndTransform(i),
          t = 0,
          e = this.sprayChunks.length;
        t < e;
        t++
      )
        this.render(this.sprayChunks[t]);
      i.restore();
    },
    addSprayChunk: function(t) {
      this.sprayChunkPoints = [];
      var e,
        i,
        r,
        n,
        s = this.width / 2;
      for (n = 0; n < this.density; n++) {
        (e = fabric.util.getRandomInt(t.x - s, t.x + s)),
          (i = fabric.util.getRandomInt(t.y - s, t.y + s)),
          (r = this.dotWidthVariance
            ? fabric.util.getRandomInt(
                Math.max(1, this.dotWidth - this.dotWidthVariance),
                this.dotWidth + this.dotWidthVariance
              )
            : this.dotWidth);
        var o = new fabric.Point(e, i);
        (o.width = r),
          this.randomOpacity &&
            (o.opacity = fabric.util.getRandomInt(0, 100) / 100),
          this.sprayChunkPoints.push(o);
      }
      this.sprayChunks.push(this.sprayChunkPoints);
    },
  })),
  (fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
    getPatternSrc: function() {
      var t = fabric.util.createCanvasElement(),
        e = t.getContext('2d');
      return (
        (t.width = t.height = 25),
        (e.fillStyle = this.color),
        e.beginPath(),
        e.arc(10, 10, 10, 0, 2 * Math.PI, !1),
        e.closePath(),
        e.fill(),
        t
      );
    },
    getPatternSrcFunction: function() {
      return String(this.getPatternSrc).replace(
        'this.color',
        '"' + this.color + '"'
      );
    },
    getPattern: function() {
      return this.canvas.contextTop.createPattern(
        this.source || this.getPatternSrc(),
        'repeat'
      );
    },
    _setBrushStyles: function() {
      this.callSuper('_setBrushStyles'),
        (this.canvas.contextTop.strokeStyle = this.getPattern());
    },
    createPath: function(t) {
      var e = this.callSuper('createPath', t),
        i = e._getLeftTopCoords().scalarAdd(e.strokeWidth / 2);
      return (
        (e.stroke = new fabric.Pattern({
          source: this.source || this.getPatternSrcFunction(),
          offsetX: -i.x,
          offsetY: -i.y,
        })),
        e
      );
    },
  })),
  (function() {
    var h = fabric.util.getPointer,
      a = fabric.util.degreesToRadians,
      d = fabric.util.radiansToDegrees,
      g = Math.atan2,
      c = Math.abs,
      l = fabric.StaticCanvas.supports('setLineDash');
    for (var t in ((fabric.Canvas = fabric.util.createClass(
      fabric.StaticCanvas,
      {
        initialize: function(t, e) {
          e || (e = {}),
            (this.renderAndResetBound = this.renderAndReset.bind(this)),
            (this.requestRenderAllBound = this.requestRenderAll.bind(this)),
            this._initStatic(t, e),
            this._initInteractive(),
            this._createCacheCanvas();
        },
        uniScaleTransform: !1,
        uniScaleKey: 'shiftKey',
        centeredScaling: !1,
        centeredRotation: !1,
        centeredKey: 'altKey',
        altActionKey: 'shiftKey',
        interactive: !0,
        selection: !0,
        selectionKey: 'shiftKey',
        altSelectionKey: null,
        selectionColor: 'rgba(100, 100, 255, 0.3)',
        selectionDashArray: [],
        selectionBorderColor: 'rgba(255, 255, 255, 0.3)',
        selectionLineWidth: 1,
        selectionFullyContained: !1,
        hoverCursor: 'move',
        moveCursor: 'move',
        defaultCursor: 'default',
        freeDrawingCursor: 'crosshair',
        rotationCursor: 'crosshair',
        notAllowedCursor: 'not-allowed',
        containerClass: 'canvas-container',
        perPixelTargetFind: !1,
        targetFindTolerance: 0,
        skipTargetFind: !1,
        isDrawingMode: !1,
        preserveObjectStacking: !1,
        snapAngle: 0,
        snapThreshold: null,
        stopContextMenu: !1,
        fireRightClick: !1,
        fireMiddleClick: !1,
        _initInteractive: function() {
          (this._currentTransform = null),
            (this._groupSelector = null),
            this._initWrapperElement(),
            this._createUpperCanvas(),
            this._initEventListeners(),
            this._initRetinaScaling(),
            (this.freeDrawingBrush =
              fabric.PencilBrush && new fabric.PencilBrush(this)),
            this.calcOffset();
        },
        _chooseObjectsToRender: function() {
          var t,
            e,
            i,
            r = this.getActiveObjects();
          if (0 < r.length && !this.preserveObjectStacking) {
            (e = []), (i = []);
            for (var n = 0, s = this._objects.length; n < s; n++)
              (t = this._objects[n]),
                -1 === r.indexOf(t) ? e.push(t) : i.push(t);
            1 < r.length && (this._activeObject._objects = i),
              e.push.apply(e, i);
          } else e = this._objects;
          return e;
        },
        renderAll: function() {
          !this.contextTopDirty ||
            this._groupSelector ||
            this.isDrawingMode ||
            (this.clearContext(this.contextTop), (this.contextTopDirty = !1)),
            this.hasLostContext && this.renderTopLayer(this.contextTop);
          var t = this.contextContainer;
          return this.renderCanvas(t, this._chooseObjectsToRender()), this;
        },
        renderTopLayer: function(t) {
          t.save(),
            this.isDrawingMode &&
              this._isCurrentlyDrawing &&
              (this.freeDrawingBrush && this.freeDrawingBrush._render(),
              (this.contextTopDirty = !0)),
            this.selection &&
              this._groupSelector &&
              (this._drawSelection(t), (this.contextTopDirty = !0)),
            t.restore();
        },
        renderTop: function() {
          var t = this.contextTop;
          return (
            this.clearContext(t),
            this.renderTopLayer(t),
            this.fire('after:render'),
            this
          );
        },
        _resetCurrentTransform: function() {
          var t = this._currentTransform;
          t.target.set({
            scaleX: t.original.scaleX,
            scaleY: t.original.scaleY,
            skewX: t.original.skewX,
            skewY: t.original.skewY,
            left: t.original.left,
            top: t.original.top,
          }),
            this._shouldCenterTransform(t.target)
              ? ('center' !== t.originX &&
                  ('right' === t.originX
                    ? (t.mouseXSign = -1)
                    : (t.mouseXSign = 1)),
                'center' !== t.originY &&
                  ('bottom' === t.originY
                    ? (t.mouseYSign = -1)
                    : (t.mouseYSign = 1)),
                (t.originX = 'center'),
                (t.originY = 'center'))
              : ((t.originX = t.original.originX),
                (t.originY = t.original.originY));
        },
        containsPoint: function(t, e, i) {
          var r,
            n = i || this.getPointer(t, !0);
          return (
            (r =
              e.group &&
              e.group === this._activeObject &&
              'activeSelection' === e.group.type
                ? this._normalizePointer(e.group, n)
                : { x: n.x, y: n.y }),
            e.containsPoint(r) || e._findTargetCorner(n)
          );
        },
        _normalizePointer: function(t, e) {
          var i = t.calcTransformMatrix(),
            r = fabric.util.invertTransform(i),
            n = this.restorePointerVpt(e);
          return fabric.util.transformPoint(n, r);
        },
        isTargetTransparent: function(t, e, i) {
          if (t.shouldCache() && t._cacheCanvas) {
            var r = this._normalizePointer(t, { x: e, y: i }),
              n = t.cacheTranslationX + r.x * t.zoomX,
              s = t.cacheTranslationY + r.y * t.zoomY;
            return fabric.util.isTransparent(
              t._cacheContext,
              n,
              s,
              this.targetFindTolerance
            );
          }
          var o = this.contextCache,
            a = t.selectionBackgroundColor,
            h = this.viewportTransform;
          return (
            (t.selectionBackgroundColor = ''),
            this.clearContext(o),
            o.save(),
            o.transform(h[0], h[1], h[2], h[3], h[4], h[5]),
            t.render(o),
            o.restore(),
            t === this._activeObject &&
              t._renderControls(
                o,
                { hasBorders: !1, transparentCorners: !1 },
                { hasBorders: !1 }
              ),
            (t.selectionBackgroundColor = a),
            fabric.util.isTransparent(o, e, i, this.targetFindTolerance)
          );
        },
        _isSelectionKeyPressed: function(e) {
          return '[object Array]' ===
            Object.prototype.toString.call(this.selectionKey)
            ? !!this.selectionKey.find(function(t) {
                return !0 === e[t];
              })
            : e[this.selectionKey];
        },
        _shouldClearSelection: function(t, e) {
          var i = this.getActiveObjects(),
            r = this._activeObject;
          return (
            !e ||
            (e &&
              r &&
              1 < i.length &&
              -1 === i.indexOf(e) &&
              r !== e &&
              !this._isSelectionKeyPressed(t)) ||
            (e && !e.evented) ||
            (e && !e.selectable && r && r !== e)
          );
        },
        _shouldCenterTransform: function(t) {
          if (t) {
            var e,
              i = this._currentTransform;
            return (
              'scale' === i.action ||
              'scaleX' === i.action ||
              'scaleY' === i.action
                ? (e = this.centeredScaling || t.centeredScaling)
                : 'rotate' === i.action &&
                  (e = this.centeredRotation || t.centeredRotation),
              e ? !i.altKey : i.altKey
            );
          }
        },
        _getOriginFromCorner: function(t, e) {
          var i = { x: t.originX, y: t.originY };
          return (
            'ml' === e || 'tl' === e || 'bl' === e
              ? (i.x = 'right')
              : ('mr' !== e && 'tr' !== e && 'br' !== e) || (i.x = 'left'),
            'tl' === e || 'mt' === e || 'tr' === e
              ? (i.y = 'bottom')
              : ('bl' !== e && 'mb' !== e && 'br' !== e) || (i.y = 'top'),
            i
          );
        },
        _getActionFromCorner: function(t, e, i) {
          if (!e || !t) return 'drag';
          switch (e) {
            case 'mtr':
              return 'rotate';
            case 'ml':
            case 'mr':
              return i[this.altActionKey] ? 'skewY' : 'scaleX';
            case 'mt':
            case 'mb':
              return i[this.altActionKey] ? 'skewX' : 'scaleY';
            default:
              return 'scale';
          }
        },
        _setupCurrentTransform: function(t, e, i) {
          if (e) {
            var r = this.getPointer(t),
              n = e._findTargetCorner(this.getPointer(t, !0)),
              s = this._getActionFromCorner(i, n, t),
              o = this._getOriginFromCorner(e, n);
            (this._currentTransform = {
              target: e,
              action: s,
              corner: n,
              scaleX: e.scaleX,
              scaleY: e.scaleY,
              skewX: e.skewX,
              skewY: e.skewY,
              offsetX: r.x - e.left,
              offsetY: r.y - e.top,
              originX: o.x,
              originY: o.y,
              ex: r.x,
              ey: r.y,
              lastX: r.x,
              lastY: r.y,
              theta: a(e.angle),
              width: e.width * e.scaleX,
              mouseXSign: 1,
              mouseYSign: 1,
              shiftKey: t.shiftKey,
              altKey: t[this.centeredKey],
              original: fabric.util.saveObjectTransform(e),
            }),
              (this._currentTransform.original.originX = o.x),
              (this._currentTransform.original.originY = o.y),
              this._resetCurrentTransform(),
              this._beforeTransform(t);
          }
        },
        _translateObject: function(t, e) {
          var i = this._currentTransform,
            r = i.target,
            n = t - i.offsetX,
            s = e - i.offsetY,
            o = !r.get('lockMovementX') && r.left !== n,
            a = !r.get('lockMovementY') && r.top !== s;
          return o && r.set('left', n), a && r.set('top', s), o || a;
        },
        _changeSkewTransformOrigin: function(t, e, i) {
          var r = 'originX',
            n = { 0: 'center' },
            s = e.target.skewX,
            o = 'left',
            a = 'right',
            h = 'mt' === e.corner || 'ml' === e.corner ? 1 : -1,
            c = 1;
          (t = 0 < t ? 1 : -1),
            'y' === i &&
              ((s = e.target.skewY),
              (o = 'top'),
              (a = 'bottom'),
              (r = 'originY')),
            (n[-1] = o),
            (n[1] = a),
            e.target.flipX && (c *= -1),
            e.target.flipY && (c *= -1),
            0 === s
              ? ((e.skewSign = -h * t * c), (e[r] = n[-t]))
              : ((s = 0 < s ? 1 : -1), (e.skewSign = s), (e[r] = n[s * h * c]));
        },
        _skewObject: function(t, e, i) {
          var r,
            n = this._currentTransform,
            s = n.target,
            o = s.get('lockSkewingX'),
            a = s.get('lockSkewingY');
          if ((o && 'x' === i) || (a && 'y' === i)) return !1;
          var h,
            c,
            l = s.getCenterPoint(),
            u = s.toLocalPoint(new fabric.Point(t, e), 'center', 'center')[i],
            f = s.toLocalPoint(
              new fabric.Point(n.lastX, n.lastY),
              'center',
              'center'
            )[i],
            d = s._getTransformedDimensions();
          return (
            this._changeSkewTransformOrigin(u - f, n, i),
            (h = s.toLocalPoint(new fabric.Point(t, e), n.originX, n.originY)[
              i
            ]),
            (c = s.translateToOriginPoint(l, n.originX, n.originY)),
            (r = this._setObjectSkew(h, n, i, d)),
            (n.lastX = t),
            (n.lastY = e),
            s.setPositionByOrigin(c, n.originX, n.originY),
            r
          );
        },
        _setObjectSkew: function(t, e, i, r) {
          var n,
            s,
            o,
            a,
            h,
            c,
            l,
            u,
            f,
            d,
            g = e.target,
            p = e.skewSign;
          return (
            'x' === i
              ? ((h = 'y'), (c = 'Y'), (l = 'X'), (f = 0), (d = g.skewY))
              : ((h = 'x'), (c = 'X'), (l = 'Y'), (f = g.skewX), (d = 0)),
            (a = g._getTransformedDimensions(f, d)),
            (u = 2 * Math.abs(t) - a[i]) <= 2
              ? (n = 0)
              : ((n =
                  p * Math.atan(u / g['scale' + l] / (a[h] / g['scale' + c]))),
                (n = fabric.util.radiansToDegrees(n))),
            (s = g['skew' + l] !== n),
            g.set('skew' + l, n),
            0 !== g['skew' + c] &&
              ((o = g._getTransformedDimensions()),
              (n = (r[h] / o[h]) * g['scale' + c]),
              g.set('scale' + c, n)),
            s
          );
        },
        _scaleObject: function(t, e, i) {
          var r = this._currentTransform,
            n = r.target,
            s = n.lockScalingX,
            o = n.lockScalingY,
            a = n.lockScalingFlip;
          if (s && o) return !1;
          var h,
            c = n.translateToOriginPoint(
              n.getCenterPoint(),
              r.originX,
              r.originY
            ),
            l = n.toLocalPoint(new fabric.Point(t, e), r.originX, r.originY),
            u = n._getTransformedDimensions();
          return (
            this._setLocalMouse(l, r),
            (h = this._setObjectScale(l, r, s, o, i, a, u)),
            n.setPositionByOrigin(c, r.originX, r.originY),
            h
          );
        },
        _setObjectScale: function(t, e, i, r, n, s, o) {
          var a,
            h,
            c,
            l,
            u = e.target,
            f = !1,
            d = !1,
            g = !1;
          return (
            (c = (t.x * u.scaleX) / o.x),
            (l = (t.y * u.scaleY) / o.y),
            (a = u.scaleX !== c),
            (h = u.scaleY !== l),
            s && c <= 0 && c < u.scaleX && ((f = !0), (t.x = 0)),
            s && l <= 0 && l < u.scaleY && ((d = !0), (t.y = 0)),
            'equally' !== n || i || r
              ? n
                ? 'x' !== n || u.get('lockUniScaling')
                  ? 'y' !== n ||
                    u.get('lockUniScaling') ||
                    d ||
                    r ||
                    (u.set('scaleY', l) && (g = g || h))
                  : f || i || (u.set('scaleX', c) && (g = g || a))
                : (f || i || (u.set('scaleX', c) && (g = g || a)),
                  d || r || (u.set('scaleY', l) && (g = g || h)))
              : (g = this._scaleObjectEqually(t, u, e, o)),
            (e.newScaleX = c),
            (e.newScaleY = l),
            f || d || this._flipObject(e, n),
            g
          );
        },
        _scaleObjectEqually: function(t, e, i, r) {
          var n,
            s = t.y + t.x,
            o =
              (r.y * i.original.scaleY) / e.scaleY +
              (r.x * i.original.scaleX) / e.scaleX,
            a = t.x < 0 ? -1 : 1,
            h = t.y < 0 ? -1 : 1;
          return (
            (i.newScaleX = a * Math.abs((i.original.scaleX * s) / o)),
            (i.newScaleY = h * Math.abs((i.original.scaleY * s) / o)),
            (n = i.newScaleX !== e.scaleX || i.newScaleY !== e.scaleY),
            e.set('scaleX', i.newScaleX),
            e.set('scaleY', i.newScaleY),
            n
          );
        },
        _flipObject: function(t, e) {
          t.newScaleX < 0 &&
            'y' !== e &&
            ('left' === t.originX
              ? (t.originX = 'right')
              : 'right' === t.originX && (t.originX = 'left')),
            t.newScaleY < 0 &&
              'x' !== e &&
              ('top' === t.originY
                ? (t.originY = 'bottom')
                : 'bottom' === t.originY && (t.originY = 'top'));
        },
        _setLocalMouse: function(t, e) {
          var i = e.target,
            r = this.getZoom(),
            n = i.padding / r;
          'right' === e.originX
            ? (t.x *= -1)
            : 'center' === e.originX &&
              ((t.x *= 2 * e.mouseXSign),
              t.x < 0 && (e.mouseXSign = -e.mouseXSign)),
            'bottom' === e.originY
              ? (t.y *= -1)
              : 'center' === e.originY &&
                ((t.y *= 2 * e.mouseYSign),
                t.y < 0 && (e.mouseYSign = -e.mouseYSign)),
            c(t.x) > n ? (t.x < 0 ? (t.x += n) : (t.x -= n)) : (t.x = 0),
            c(t.y) > n ? (t.y < 0 ? (t.y += n) : (t.y -= n)) : (t.y = 0);
        },
        _rotateObject: function(t, e) {
          var i = this._currentTransform,
            r = i.target,
            n = r.translateToOriginPoint(
              r.getCenterPoint(),
              i.originX,
              i.originY
            );
          if (r.lockRotation) return !1;
          var s = g(i.ey - n.y, i.ex - n.x),
            o = g(e - n.y, t - n.x),
            a = d(o - s + i.theta),
            h = !0;
          if (0 < r.snapAngle) {
            var c = r.snapAngle,
              l = r.snapThreshold || c,
              u = Math.ceil(a / c) * c,
              f = Math.floor(a / c) * c;
            Math.abs(a - f) < l ? (a = f) : Math.abs(a - u) < l && (a = u);
          }
          return (
            a < 0 && (a = 360 + a),
            (a %= 360),
            r.angle === a
              ? (h = !1)
              : ((r.angle = a), r.setPositionByOrigin(n, i.originX, i.originY)),
            h
          );
        },
        setCursor: function(t) {
          this.upperCanvasEl.style.cursor = t;
        },
        _drawSelection: function(t) {
          var e = this._groupSelector,
            i = e.left,
            r = e.top,
            n = c(i),
            s = c(r);
          if (
            (this.selectionColor &&
              ((t.fillStyle = this.selectionColor),
              t.fillRect(
                e.ex - (0 < i ? 0 : -i),
                e.ey - (0 < r ? 0 : -r),
                n,
                s
              )),
            this.selectionLineWidth && this.selectionBorderColor)
          )
            if (
              ((t.lineWidth = this.selectionLineWidth),
              (t.strokeStyle = this.selectionBorderColor),
              1 < this.selectionDashArray.length && !l)
            ) {
              var o = e.ex + 0.5 - (0 < i ? 0 : n),
                a = e.ey + 0.5 - (0 < r ? 0 : s);
              t.beginPath(),
                fabric.util.drawDashedLine(
                  t,
                  o,
                  a,
                  o + n,
                  a,
                  this.selectionDashArray
                ),
                fabric.util.drawDashedLine(
                  t,
                  o,
                  a + s - 1,
                  o + n,
                  a + s - 1,
                  this.selectionDashArray
                ),
                fabric.util.drawDashedLine(
                  t,
                  o,
                  a,
                  o,
                  a + s,
                  this.selectionDashArray
                ),
                fabric.util.drawDashedLine(
                  t,
                  o + n - 1,
                  a,
                  o + n - 1,
                  a + s,
                  this.selectionDashArray
                ),
                t.closePath(),
                t.stroke();
            } else
              fabric.Object.prototype._setLineDash.call(
                this,
                t,
                this.selectionDashArray
              ),
                t.strokeRect(
                  e.ex + 0.5 - (0 < i ? 0 : n),
                  e.ey + 0.5 - (0 < r ? 0 : s),
                  n,
                  s
                );
        },
        findTarget: function(t, e) {
          if (!this.skipTargetFind) {
            var i,
              r,
              n = this.getPointer(t, !0),
              s = this._activeObject,
              o = this.getActiveObjects();
            if (
              ((this.targets = []),
              1 < o.length && !e && s === this._searchPossibleTargets([s], n))
            )
              return s;
            if (1 === o.length && s._findTargetCorner(n)) return s;
            if (1 === o.length && s === this._searchPossibleTargets([s], n)) {
              if (!this.preserveObjectStacking) return s;
              (i = s), (r = this.targets), (this.targets = []);
            }
            var a = this._searchPossibleTargets(this._objects, n);
            return (
              t[this.altSelectionKey] &&
                a &&
                i &&
                a !== i &&
                ((a = i), (this.targets = r)),
              a
            );
          }
        },
        _checkTarget: function(t, e, i) {
          if (e && e.visible && e.evented && this.containsPoint(null, e, t)) {
            if (
              (!this.perPixelTargetFind && !e.perPixelTargetFind) ||
              e.isEditing
            )
              return !0;
            if (!this.isTargetTransparent(e, i.x, i.y)) return !0;
          }
        },
        _searchPossibleTargets: function(t, e) {
          for (var i, r, n = t.length; n--; ) {
            var s = t[n],
              o =
                s.group && 'activeSelection' !== s.group.type
                  ? this._normalizePointer(s.group, e)
                  : e;
            if (this._checkTarget(o, s, e)) {
              (i = t[n]).subTargetCheck &&
                i instanceof fabric.Group &&
                (r = this._searchPossibleTargets(i._objects, e)) &&
                this.targets.push(r);
              break;
            }
          }
          return i;
        },
        restorePointerVpt: function(t) {
          return fabric.util.transformPoint(
            t,
            fabric.util.invertTransform(this.viewportTransform)
          );
        },
        getPointer: function(t, e) {
          if (this._absolutePointer && !e) return this._absolutePointer;
          if (this._pointer && e) return this._pointer;
          var i,
            r = h(t),
            n = this.upperCanvasEl,
            s = n.getBoundingClientRect(),
            o = s.width || 0,
            a = s.height || 0;
          return (
            (o && a) ||
              ('top' in s && 'bottom' in s && (a = Math.abs(s.top - s.bottom)),
              'right' in s && 'left' in s && (o = Math.abs(s.right - s.left))),
            this.calcOffset(),
            (r.x = r.x - this._offset.left),
            (r.y = r.y - this._offset.top),
            e || (r = this.restorePointerVpt(r)),
            (i =
              0 === o || 0 === a
                ? { width: 1, height: 1 }
                : { width: n.width / o, height: n.height / a }),
            { x: r.x * i.width, y: r.y * i.height }
          );
        },
        _createUpperCanvas: function() {
          var t = this.lowerCanvasEl.className.replace(
            /\s*lower-canvas\s*/,
            ''
          );
          this.upperCanvasEl
            ? (this.upperCanvasEl.className = '')
            : (this.upperCanvasEl = this._createCanvasElement()),
            fabric.util.addClass(this.upperCanvasEl, 'upper-canvas ' + t),
            this.wrapperEl.appendChild(this.upperCanvasEl),
            this._copyCanvasStyle(this.lowerCanvasEl, this.upperCanvasEl),
            this._applyCanvasStyle(this.upperCanvasEl),
            (this.contextTop = this.upperCanvasEl.getContext('2d'));
        },
        _createCacheCanvas: function() {
          (this.cacheCanvasEl = this._createCanvasElement()),
            this.cacheCanvasEl.setAttribute('width', this.width),
            this.cacheCanvasEl.setAttribute('height', this.height),
            (this.contextCache = this.cacheCanvasEl.getContext('2d'));
        },
        _initWrapperElement: function() {
          (this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', {
            class: this.containerClass,
          })),
            fabric.util.setStyle(this.wrapperEl, {
              width: this.width + 'px',
              height: this.height + 'px',
              position: 'relative',
            }),
            fabric.util.makeElementUnselectable(this.wrapperEl);
        },
        _applyCanvasStyle: function(t) {
          var e = this.width || t.width,
            i = this.height || t.height;
          fabric.util.setStyle(t, {
            position: 'absolute',
            width: e + 'px',
            height: i + 'px',
            left: 0,
            top: 0,
            'touch-action': this.allowTouchScrolling ? 'manipulation' : 'none',
          }),
            (t.width = e),
            (t.height = i),
            fabric.util.makeElementUnselectable(t);
        },
        _copyCanvasStyle: function(t, e) {
          e.style.cssText = t.style.cssText;
        },
        getSelectionContext: function() {
          return this.contextTop;
        },
        getSelectionElement: function() {
          return this.upperCanvasEl;
        },
        getActiveObject: function() {
          return this._activeObject;
        },
        getActiveObjects: function() {
          var t = this._activeObject;
          return t
            ? 'activeSelection' === t.type && t._objects
              ? t._objects.slice(0)
              : [t]
            : [];
        },
        _onObjectRemoved: function(t) {
          t === this._activeObject &&
            (this.fire('before:selection:cleared', { target: t }),
            this._discardActiveObject(),
            this.fire('selection:cleared', { target: t }),
            t.fire('deselected')),
            this._hoveredTarget === t && (this._hoveredTarget = null),
            this.callSuper('_onObjectRemoved', t);
        },
        _fireSelectionEvents: function(e, t) {
          var i = !1,
            r = this.getActiveObjects(),
            n = [],
            s = [],
            o = { e: t };
          e.forEach(function(t) {
            -1 === r.indexOf(t) &&
              ((i = !0), t.fire('deselected', o), s.push(t));
          }),
            r.forEach(function(t) {
              -1 === e.indexOf(t) &&
                ((i = !0), t.fire('selected', o), n.push(t));
            }),
            0 < e.length && 0 < r.length
              ? ((o.selected = n),
                (o.deselected = s),
                (o.updated = n[0] || s[0]),
                (o.target = this._activeObject),
                i && this.fire('selection:updated', o))
              : 0 < r.length
              ? (1 === r.length &&
                  ((o.target = n[0]), this.fire('object:selected', o)),
                (o.selected = n),
                (o.target = this._activeObject),
                this.fire('selection:created', o))
              : 0 < e.length &&
                ((o.deselected = s), this.fire('selection:cleared', o));
        },
        setActiveObject: function(t, e) {
          var i = this.getActiveObjects();
          return (
            this._setActiveObject(t, e), this._fireSelectionEvents(i, e), this
          );
        },
        _setActiveObject: function(t, e) {
          return (
            this._activeObject !== t &&
            (!!this._discardActiveObject(e, t) &&
              (!t.onSelect({ e: e }) && ((this._activeObject = t), !0)))
          );
        },
        _discardActiveObject: function(t, e) {
          var i = this._activeObject;
          if (i) {
            if (i.onDeselect({ e: t, object: e })) return !1;
            this._activeObject = null;
          }
          return !0;
        },
        discardActiveObject: function(t) {
          var e = this.getActiveObjects();
          return (
            e.length &&
              this.fire('before:selection:cleared', { target: e[0], e: t }),
            this._discardActiveObject(t),
            this._fireSelectionEvents(e, t),
            this
          );
        },
        dispose: function() {
          var t = this.wrapperEl;
          return (
            this.removeListeners(),
            t.removeChild(this.upperCanvasEl),
            t.removeChild(this.lowerCanvasEl),
            (this.contextCache = null),
            (this.contextTop = null),
            ['upperCanvasEl', 'cacheCanvasEl'].forEach(
              function(t) {
                fabric.util.cleanUpJsdomNode(this[t]), (this[t] = void 0);
              }.bind(this)
            ),
            t.parentNode &&
              t.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl),
            delete this.wrapperEl,
            fabric.StaticCanvas.prototype.dispose.call(this),
            this
          );
        },
        clear: function() {
          return (
            this.discardActiveObject(),
            this.clearContext(this.contextTop),
            this.callSuper('clear')
          );
        },
        drawControls: function(t) {
          var e = this._activeObject;
          e && e._renderControls(t);
        },
        _toObject: function(t, e, i) {
          var r = this._realizeGroupTransformOnObject(t),
            n = this.callSuper('_toObject', t, e, i);
          return this._unwindGroupTransformOnObject(t, r), n;
        },
        _realizeGroupTransformOnObject: function(e) {
          if (
            e.group &&
            'activeSelection' === e.group.type &&
            this._activeObject === e.group
          ) {
            var i = {};
            return (
              [
                'angle',
                'flipX',
                'flipY',
                'left',
                'scaleX',
                'scaleY',
                'skewX',
                'skewY',
                'top',
              ].forEach(function(t) {
                i[t] = e[t];
              }),
              this._activeObject.realizeTransform(e),
              i
            );
          }
          return null;
        },
        _unwindGroupTransformOnObject: function(t, e) {
          e && t.set(e);
        },
        _setSVGObject: function(t, e, i) {
          var r = this._realizeGroupTransformOnObject(e);
          this.callSuper('_setSVGObject', t, e, i),
            this._unwindGroupTransformOnObject(e, r);
        },
        setViewportTransform: function(t) {
          this.renderOnAddRemove &&
            this._activeObject &&
            this._activeObject.isEditing &&
            this._activeObject.clearContextTop(),
            fabric.StaticCanvas.prototype.setViewportTransform.call(this, t);
        },
      }
    )),
    fabric.StaticCanvas))
      'prototype' !== t && (fabric.Canvas[t] = fabric.StaticCanvas[t]);
    fabric.isTouchSupported &&
      (fabric.Canvas.prototype._setCursorFromEvent = function() {});
  })(),
  (function() {
    var n = { mt: 0, tr: 1, mr: 2, br: 3, mb: 4, bl: 5, ml: 6, tl: 7 },
      i = fabric.util.addListener,
      r = fabric.util.removeListener,
      s = { passive: !1 };
    function o(t, e) {
      return 'which' in t ? t.which === e : t.button === e - 1;
    }
    fabric.util.object.extend(fabric.Canvas.prototype, {
      cursorMap: [
        'n-resize',
        'ne-resize',
        'e-resize',
        'se-resize',
        's-resize',
        'sw-resize',
        'w-resize',
        'nw-resize',
      ],
      _initEventListeners: function() {
        this.removeListeners(), this._bindEvents(), this.addOrRemove(i, 'add');
      },
      addOrRemove: function(t, e) {
        t(fabric.window, 'resize', this._onResize),
          t(this.upperCanvasEl, 'mousedown', this._onMouseDown),
          t(this.upperCanvasEl, 'mousemove', this._onMouseMove, s),
          t(this.upperCanvasEl, 'mouseout', this._onMouseOut),
          t(this.upperCanvasEl, 'mouseenter', this._onMouseEnter),
          t(this.upperCanvasEl, 'wheel', this._onMouseWheel),
          t(this.upperCanvasEl, 'contextmenu', this._onContextMenu),
          t(this.upperCanvasEl, 'dblclick', this._onDoubleClick),
          t(this.upperCanvasEl, 'touchstart', this._onMouseDown, s),
          t(this.upperCanvasEl, 'touchmove', this._onMouseMove, s),
          t(this.upperCanvasEl, 'dragover', this._onDragOver),
          t(this.upperCanvasEl, 'dragenter', this._onDragEnter),
          t(this.upperCanvasEl, 'dragleave', this._onDragLeave),
          t(this.upperCanvasEl, 'drop', this._onDrop),
          'undefined' != typeof eventjs &&
            e in eventjs &&
            (eventjs[e](this.upperCanvasEl, 'gesture', this._onGesture),
            eventjs[e](this.upperCanvasEl, 'drag', this._onDrag),
            eventjs[e](
              this.upperCanvasEl,
              'orientation',
              this._onOrientationChange
            ),
            eventjs[e](this.upperCanvasEl, 'shake', this._onShake),
            eventjs[e](this.upperCanvasEl, 'longpress', this._onLongPress));
      },
      removeListeners: function() {
        this.addOrRemove(r, 'remove'),
          r(fabric.document, 'mouseup', this._onMouseUp),
          r(fabric.document, 'touchend', this._onMouseUp, s),
          r(fabric.document, 'mousemove', this._onMouseMove, s),
          r(fabric.document, 'touchmove', this._onMouseMove, s);
      },
      _bindEvents: function() {
        this.eventsBound ||
          ((this._onMouseDown = this._onMouseDown.bind(this)),
          (this._onMouseMove = this._onMouseMove.bind(this)),
          (this._onMouseUp = this._onMouseUp.bind(this)),
          (this._onResize = this._onResize.bind(this)),
          (this._onGesture = this._onGesture.bind(this)),
          (this._onDrag = this._onDrag.bind(this)),
          (this._onShake = this._onShake.bind(this)),
          (this._onLongPress = this._onLongPress.bind(this)),
          (this._onOrientationChange = this._onOrientationChange.bind(this)),
          (this._onMouseWheel = this._onMouseWheel.bind(this)),
          (this._onMouseOut = this._onMouseOut.bind(this)),
          (this._onMouseEnter = this._onMouseEnter.bind(this)),
          (this._onContextMenu = this._onContextMenu.bind(this)),
          (this._onDoubleClick = this._onDoubleClick.bind(this)),
          (this._onDragOver = this._onDragOver.bind(this)),
          (this._onDragEnter = this._simpleEventHandler.bind(
            this,
            'dragenter'
          )),
          (this._onDragLeave = this._simpleEventHandler.bind(
            this,
            'dragleave'
          )),
          (this._onDrop = this._simpleEventHandler.bind(this, 'drop')),
          (this.eventsBound = !0));
      },
      _onGesture: function(t, e) {
        this.__onTransformGesture && this.__onTransformGesture(t, e);
      },
      _onDrag: function(t, e) {
        this.__onDrag && this.__onDrag(t, e);
      },
      _onMouseWheel: function(t) {
        this.__onMouseWheel(t);
      },
      _onMouseOut: function(t) {
        var e = this._hoveredTarget;
        this.fire('mouse:out', { target: e, e: t }),
          (this._hoveredTarget = null),
          e && e.fire('mouseout', { e: t }),
          this._iTextInstances &&
            this._iTextInstances.forEach(function(t) {
              t.isEditing && t.hiddenTextarea.focus();
            });
      },
      _onMouseEnter: function(t) {
        this.findTarget(t) ||
          (this.fire('mouse:over', { target: null, e: t }),
          (this._hoveredTarget = null));
      },
      _onOrientationChange: function(t, e) {
        this.__onOrientationChange && this.__onOrientationChange(t, e);
      },
      _onShake: function(t, e) {
        this.__onShake && this.__onShake(t, e);
      },
      _onLongPress: function(t, e) {
        this.__onLongPress && this.__onLongPress(t, e);
      },
      _onDragOver: function(t) {
        t.preventDefault();
        var e = this._simpleEventHandler('dragover', t);
        this._fireEnterLeaveEvents(e, t);
      },
      _onContextMenu: function(t) {
        return (
          this.stopContextMenu && (t.stopPropagation(), t.preventDefault()), !1
        );
      },
      _onDoubleClick: function(t) {
        this._cacheTransformEventData(t),
          this._handleEvent(t, 'dblclick'),
          this._resetTransformEventData(t);
      },
      _onMouseDown: function(t) {
        this.__onMouseDown(t),
          this._resetTransformEventData(),
          i(fabric.document, 'touchend', this._onMouseUp, s),
          i(fabric.document, 'touchmove', this._onMouseMove, s),
          r(this.upperCanvasEl, 'mousemove', this._onMouseMove, s),
          r(this.upperCanvasEl, 'touchmove', this._onMouseMove, s),
          'touchstart' === t.type
            ? r(this.upperCanvasEl, 'mousedown', this._onMouseDown)
            : (i(fabric.document, 'mouseup', this._onMouseUp),
              i(fabric.document, 'mousemove', this._onMouseMove, s));
      },
      _onMouseUp: function(t) {
        if (
          (this.__onMouseUp(t),
          this._resetTransformEventData(),
          r(fabric.document, 'mouseup', this._onMouseUp),
          r(fabric.document, 'touchend', this._onMouseUp, s),
          r(fabric.document, 'mousemove', this._onMouseMove, s),
          r(fabric.document, 'touchmove', this._onMouseMove, s),
          i(this.upperCanvasEl, 'mousemove', this._onMouseMove, s),
          i(this.upperCanvasEl, 'touchmove', this._onMouseMove, s),
          'touchend' === t.type)
        ) {
          var e = this;
          setTimeout(function() {
            i(e.upperCanvasEl, 'mousedown', e._onMouseDown);
          }, 400);
        }
      },
      _onMouseMove: function(t) {
        !this.allowTouchScrolling && t.preventDefault && t.preventDefault(),
          this.__onMouseMove(t);
      },
      _onResize: function() {
        this.calcOffset();
      },
      _shouldRender: function(t) {
        var e = this._activeObject;
        return !!(!!e != !!t || (e && t && e !== t)) || (e && e.isEditing, !1);
      },
      __onMouseUp: function(t) {
        var e,
          i = this._currentTransform,
          r = this._groupSelector,
          n = !1,
          s = !r || (0 === r.left && 0 === r.top);
        if (
          (this._cacheTransformEventData(t),
          (e = this._target),
          this._handleEvent(t, 'up:before'),
          !o(t, 3))
        )
          return o(t, 2)
            ? (this.fireMiddleClick && this._handleEvent(t, 'up', 2, s),
              void this._resetTransformEventData())
            : void (this.isDrawingMode && this._isCurrentlyDrawing
                ? this._onMouseUpInDrawingMode(t)
                : (i &&
                    (this._finalizeCurrentTransform(t),
                    (n = i.actionPerformed)),
                  s ||
                    (this._maybeGroupObjects(t),
                    n || (n = this._shouldRender(e))),
                  e && (e.isMoving = !1),
                  this._setCursorFromEvent(t, e),
                  this._handleEvent(t, 'up', 1, s),
                  (this._groupSelector = null),
                  (this._currentTransform = null),
                  e && (e.__corner = 0),
                  n ? this.requestRenderAll() : s || this.renderTop()));
        this.fireRightClick && this._handleEvent(t, 'up', 3, s);
      },
      _simpleEventHandler: function(t, e) {
        var i = this.findTarget(e),
          r = this.targets,
          n = { e: e, target: i, subTargets: r };
        if ((this.fire(t, n), i && i.fire(t, n), !r)) return i;
        for (var s = 0; s < r.length; s++) r[s].fire(t, n);
        return i;
      },
      _handleEvent: function(t, e, i, r) {
        var n = this._target,
          s = this.targets || [],
          o = {
            e: t,
            target: n,
            subTargets: s,
            button: i || 1,
            isClick: r || !1,
            pointer: this._pointer,
            absolutePointer: this._absolutePointer,
            transform: this._currentTransform,
          };
        this.fire('mouse:' + e, o), n && n.fire('mouse' + e, o);
        for (var a = 0; a < s.length; a++) s[a].fire('mouse' + e, o);
      },
      _finalizeCurrentTransform: function(t) {
        var e,
          i = this._currentTransform,
          r = i.target,
          n = { e: t, target: r, transform: i };
        r._scaling && (r._scaling = !1),
          r.setCoords(),
          (i.actionPerformed || (this.stateful && r.hasStateChanged())) &&
            (i.actionPerformed &&
              ((e = this._addEventOptions(n, i)), this._fire(e, n)),
            this._fire('modified', n));
      },
      _addEventOptions: function(t, e) {
        var i, r;
        switch (e.action) {
          case 'scaleX':
            (i = 'scaled'), (r = 'x');
            break;
          case 'scaleY':
            (i = 'scaled'), (r = 'y');
            break;
          case 'skewX':
            (i = 'skewed'), (r = 'x');
            break;
          case 'skewY':
            (i = 'skewed'), (r = 'y');
            break;
          case 'scale':
            (i = 'scaled'), (r = 'equally');
            break;
          case 'rotate':
            i = 'rotated';
            break;
          case 'drag':
            i = 'moved';
        }
        return (t.by = r), i;
      },
      _onMouseDownInDrawingMode: function(t) {
        (this._isCurrentlyDrawing = !0),
          this.getActiveObject() &&
            this.discardActiveObject(t).requestRenderAll(),
          this.clipTo && fabric.util.clipContext(this, this.contextTop);
        var e = this.getPointer(t);
        this.freeDrawingBrush.onMouseDown(e), this._handleEvent(t, 'down');
      },
      _onMouseMoveInDrawingMode: function(t) {
        if (this._isCurrentlyDrawing) {
          var e = this.getPointer(t);
          this.freeDrawingBrush.onMouseMove(e);
        }
        this.setCursor(this.freeDrawingCursor), this._handleEvent(t, 'move');
      },
      _onMouseUpInDrawingMode: function(t) {
        (this._isCurrentlyDrawing = !1),
          this.clipTo && this.contextTop.restore(),
          this.freeDrawingBrush.onMouseUp(),
          this._handleEvent(t, 'up');
      },
      __onMouseDown: function(t) {
        this._cacheTransformEventData(t), this._handleEvent(t, 'down:before');
        var e = this._target;
        if (o(t, 3)) this.fireRightClick && this._handleEvent(t, 'down', 3);
        else if (o(t, 2))
          this.fireMiddleClick && this._handleEvent(t, 'down', 2);
        else if (this.isDrawingMode) this._onMouseDownInDrawingMode(t);
        else if (!this._currentTransform) {
          var i = this._pointer;
          this._previousPointer = i;
          var r = this._shouldRender(e),
            n = this._shouldGroup(t, e);
          if (
            (this._shouldClearSelection(t, e)
              ? this.discardActiveObject(t)
              : n && (this._handleGrouping(t, e), (e = this._activeObject)),
            !this.selection ||
              (e &&
                (e.selectable || e.isEditing || e === this._activeObject)) ||
              (this._groupSelector = { ex: i.x, ey: i.y, top: 0, left: 0 }),
            e)
          ) {
            var s = e === this._activeObject;
            e.selectable && this.setActiveObject(e, t),
              e !== this._activeObject ||
                (!e.__corner && n) ||
                this._setupCurrentTransform(t, e, s);
          }
          this._handleEvent(t, 'down'), (r || n) && this.requestRenderAll();
        }
      },
      _resetTransformEventData: function() {
        (this._target = null),
          (this._pointer = null),
          (this._absolutePointer = null);
      },
      _cacheTransformEventData: function(t) {
        this._resetTransformEventData(),
          (this._pointer = this.getPointer(t, !0)),
          (this._absolutePointer = this.restorePointerVpt(this._pointer)),
          (this._target = this._currentTransform
            ? this._currentTransform.target
            : this.findTarget(t) || null);
      },
      _beforeTransform: function(t) {
        var e = this._currentTransform;
        this.stateful && e.target.saveState(),
          this.fire('before:transform', { e: t, transform: e }),
          e.corner && this.onBeforeScaleRotate(e.target);
      },
      __onMouseMove: function(t) {
        var e, i;
        if (
          (this._handleEvent(t, 'move:before'),
          this._cacheTransformEventData(t),
          this.isDrawingMode)
        )
          this._onMouseMoveInDrawingMode(t);
        else if (!(void 0 !== t.touches && 1 < t.touches.length)) {
          var r = this._groupSelector;
          r
            ? ((i = this._pointer),
              (r.left = i.x - r.ex),
              (r.top = i.y - r.ey),
              this.renderTop())
            : this._currentTransform
            ? this._transformObject(t)
            : ((e = this.findTarget(t) || null),
              this._setCursorFromEvent(t, e),
              this._fireOverOutEvents(e, t)),
            this._handleEvent(t, 'move'),
            this._resetTransformEventData();
        }
      },
      _fireOverOutEvents: function(t, e) {
        this.fireSynteticInOutEvents(t, e, {
          targetName: '_hoveredTarget',
          canvasEvtOut: 'mouse:out',
          evtOut: 'mouseout',
          canvasEvtIn: 'mouse:over',
          evtIn: 'mouseover',
        });
      },
      _fireEnterLeaveEvents: function(t, e) {
        this.fireSynteticInOutEvents(t, e, {
          targetName: '_draggedoverTarget',
          evtOut: 'dragleave',
          evtIn: 'dragenter',
        });
      },
      fireSynteticInOutEvents: function(t, e, i) {
        var r,
          n,
          s,
          o = this[i.targetName],
          a = o !== t,
          h = i.canvasEvtIn,
          c = i.canvasEvtOut;
        a &&
          ((r = { e: e, target: t, previousTarget: o }),
          (n = { e: e, target: o, nextTarget: t }),
          (this[i.targetName] = t)),
          (s = t && a),
          o && a && (c && this.fire(c, n), o.fire(i.evtOut, n)),
          s && (h && this.fire(h, r), t.fire(i.evtIn, r));
      },
      __onMouseWheel: function(t) {
        this._cacheTransformEventData(t),
          this._handleEvent(t, 'wheel'),
          this._resetTransformEventData();
      },
      _transformObject: function(t) {
        var e = this.getPointer(t),
          i = this._currentTransform;
        (i.reset = !1),
          (i.target.isMoving = !0),
          (i.shiftKey = t.shiftKey),
          (i.altKey = t[this.centeredKey]),
          this._beforeScaleTransform(t, i),
          this._performTransformAction(t, i, e),
          i.actionPerformed && this.requestRenderAll();
      },
      _performTransformAction: function(t, e, i) {
        var r = i.x,
          n = i.y,
          s = e.action,
          o = !1,
          a = { target: e.target, e: t, transform: e, pointer: i };
        'rotate' === s
          ? (o = this._rotateObject(r, n)) && this._fire('rotating', a)
          : 'scale' === s
          ? (o = this._onScale(t, e, r, n)) && this._fire('scaling', a)
          : 'scaleX' === s
          ? (o = this._scaleObject(r, n, 'x')) && this._fire('scaling', a)
          : 'scaleY' === s
          ? (o = this._scaleObject(r, n, 'y')) && this._fire('scaling', a)
          : 'skewX' === s
          ? (o = this._skewObject(r, n, 'x')) && this._fire('skewing', a)
          : 'skewY' === s
          ? (o = this._skewObject(r, n, 'y')) && this._fire('skewing', a)
          : (o = this._translateObject(r, n)) &&
            (this._fire('moving', a),
            this.setCursor(a.target.moveCursor || this.moveCursor)),
          (e.actionPerformed = e.actionPerformed || o);
      },
      _fire: function(t, e) {
        this.fire('object:' + t, e), e.target.fire(t, e);
      },
      _beforeScaleTransform: function(t, e) {
        if (
          'scale' === e.action ||
          'scaleX' === e.action ||
          'scaleY' === e.action
        ) {
          var i = this._shouldCenterTransform(e.target);
          ((i && ('center' !== e.originX || 'center' !== e.originY)) ||
            (!i && 'center' === e.originX && 'center' === e.originY)) &&
            (this._resetCurrentTransform(), (e.reset = !0));
        }
      },
      _onScale: function(t, e, i, r) {
        return this._isUniscalePossible(t, e.target)
          ? ((e.currentAction = 'scale'), this._scaleObject(i, r))
          : (e.reset ||
              'scale' !== e.currentAction ||
              this._resetCurrentTransform(),
            (e.currentAction = 'scaleEqually'),
            this._scaleObject(i, r, 'equally'));
      },
      _isUniscalePossible: function(t, e) {
        return (
          (t[this.uniScaleKey] || this.uniScaleTransform) &&
          !e.get('lockUniScaling')
        );
      },
      _setCursorFromEvent: function(t, e) {
        if (!e) return this.setCursor(this.defaultCursor), !1;
        var i = e.hoverCursor || this.hoverCursor,
          r =
            this._activeObject && 'activeSelection' === this._activeObject.type
              ? this._activeObject
              : null,
          n =
            (!r || !r.contains(e)) &&
            e._findTargetCorner(this.getPointer(t, !0));
        n ? this.setCursor(this.getCornerCursor(n, e, t)) : this.setCursor(i);
      },
      getCornerCursor: function(t, e, i) {
        return this.actionIsDisabled(t, e, i)
          ? this.notAllowedCursor
          : t in n
          ? this._getRotatedCornerCursor(t, e, i)
          : 'mtr' === t && e.hasRotatingPoint
          ? this.rotationCursor
          : this.defaultCursor;
      },
      actionIsDisabled: function(t, e, i) {
        return 'mt' === t || 'mb' === t
          ? i[this.altActionKey]
            ? e.lockSkewingX
            : e.lockScalingY
          : 'ml' === t || 'mr' === t
          ? i[this.altActionKey]
            ? e.lockSkewingY
            : e.lockScalingX
          : 'mtr' === t
          ? e.lockRotation
          : this._isUniscalePossible(i, e)
          ? e.lockScalingX && e.lockScalingY
          : e.lockScalingX || e.lockScalingY;
      },
      _getRotatedCornerCursor: function(t, e, i) {
        var r = Math.round((e.angle % 360) / 45);
        return (
          r < 0 && (r += 8),
          (r += n[t]),
          i[this.altActionKey] && n[t] % 2 == 0 && (r += 2),
          (r %= 8),
          this.cursorMap[r]
        );
      },
    });
  })(),
  (function() {
    var f = Math.min,
      d = Math.max;
    fabric.util.object.extend(fabric.Canvas.prototype, {
      _shouldGroup: function(t, e) {
        var i = this._activeObject;
        return (
          i &&
          this._isSelectionKeyPressed(t) &&
          e &&
          e.selectable &&
          this.selection &&
          (i !== e || 'activeSelection' === i.type) &&
          !e.onSelect({ e: t })
        );
      },
      _handleGrouping: function(t, e) {
        var i = this._activeObject;
        i.__corner ||
          ((e !== i || ((e = this.findTarget(t, !0)) && e.selectable)) &&
            (i && 'activeSelection' === i.type
              ? this._updateActiveSelection(e, t)
              : this._createActiveSelection(e, t)));
      },
      _updateActiveSelection: function(t, e) {
        var i = this._activeObject,
          r = i._objects.slice(0);
        i.contains(t)
          ? (i.removeWithUpdate(t),
            (this._hoveredTarget = t),
            1 === i.size() && this._setActiveObject(i.item(0), e))
          : (i.addWithUpdate(t), (this._hoveredTarget = i)),
          this._fireSelectionEvents(r, e);
      },
      _createActiveSelection: function(t, e) {
        var i = this.getActiveObjects(),
          r = this._createGroup(t);
        (this._hoveredTarget = r),
          this._setActiveObject(r, e),
          this._fireSelectionEvents(i, e);
      },
      _createGroup: function(t) {
        var e = this._objects,
          i =
            e.indexOf(this._activeObject) < e.indexOf(t)
              ? [this._activeObject, t]
              : [t, this._activeObject];
        return (
          this._activeObject.isEditing && this._activeObject.exitEditing(),
          new fabric.ActiveSelection(i, { canvas: this })
        );
      },
      _groupSelectedObjects: function(t) {
        var e,
          i = this._collectObjects(t);
        1 === i.length
          ? this.setActiveObject(i[0], t)
          : 1 < i.length &&
            ((e = new fabric.ActiveSelection(i.reverse(), { canvas: this })),
            this.setActiveObject(e, t));
      },
      _collectObjects: function(t) {
        for (
          var e,
            i = [],
            r = this._groupSelector.ex,
            n = this._groupSelector.ey,
            s = r + this._groupSelector.left,
            o = n + this._groupSelector.top,
            a = new fabric.Point(f(r, s), f(n, o)),
            h = new fabric.Point(d(r, s), d(n, o)),
            c = !this.selectionFullyContained,
            l = r === s && n === o,
            u = this._objects.length;
          u-- &&
          !(
            (e = this._objects[u]) &&
            e.selectable &&
            e.visible &&
            !e.onSelect({ e: t }) &&
            ((c && e.intersectsWithRect(a, h)) ||
              e.isContainedWithinRect(a, h) ||
              (c && e.containsPoint(a)) ||
              (c && e.containsPoint(h))) &&
            (i.push(e), l)
          );

        );
        return i;
      },
      _maybeGroupObjects: function(t) {
        this.selection && this._groupSelector && this._groupSelectedObjects(t),
          this.setCursor(this.defaultCursor),
          (this._groupSelector = null);
      },
    });
  })(),
  (function() {
    var r = fabric.StaticCanvas.supports('toDataURLWithQuality');
    fabric.util.object.extend(fabric.StaticCanvas.prototype, {
      toDataURL: function(t) {
        t || (t = {});
        var e = t.format || 'png',
          i = t.quality || 1,
          r =
            (t.multiplier || 1) *
            (t.enableRetinaScaling ? 1 : 1 / this.getRetinaScaling()),
          n = {
            left: t.left || 0,
            top: t.top || 0,
            width: t.width || 0,
            height: t.height || 0,
          };
        return this.__toDataURLWithMultiplier(e, i, n, r);
      },
      __toDataURLWithMultiplier: function(t, e, i, r) {
        var n = this.width,
          s = this.height,
          o = (i.width || this.width) * r,
          a = (i.height || this.height) * r,
          h = this.getZoom() * r,
          c = this.viewportTransform,
          l = [h, 0, 0, h, (c[4] - i.left) * r, (c[5] - i.top) * r],
          u = this.interactive,
          f = this.skipOffscreen,
          d = n !== o || s !== a;
        (this.viewportTransform = l),
          (this.skipOffscreen = !1),
          (this.interactive = !1),
          d &&
            this.setDimensions({ width: o, height: a }, { backstoreOnly: !0 }),
          this.renderAll();
        var g = this.__toDataURL(t, e, i);
        return (
          (this.interactive = u),
          (this.skipOffscreen = f),
          (this.viewportTransform = c),
          d &&
            this.setDimensions({ width: n, height: s }, { backstoreOnly: !0 }),
          this.renderAll(),
          g
        );
      },
      __toDataURL: function(t, e) {
        var i = this.contextContainer.canvas;
        return r ? i.toDataURL('image/' + t, e) : i.toDataURL('image/' + t);
      },
    });
  })(),
  fabric.util.object.extend(fabric.StaticCanvas.prototype, {
    loadFromDatalessJSON: function(t, e, i) {
      return this.loadFromJSON(t, e, i);
    },
    loadFromJSON: function(t, e, i) {
      if (t) {
        var r =
            'string' == typeof t ? JSON.parse(t) : fabric.util.object.clone(t),
          n = this,
          s = this.renderOnAddRemove;
        return (
          (this.renderOnAddRemove = !1),
          this._enlivenObjects(
            r.objects,
            function(t) {
              n.clear(),
                n._setBgOverlay(r, function() {
                  t.forEach(function(t, e) {
                    n.insertAt(t, e);
                  }),
                    (n.renderOnAddRemove = s),
                    delete r.objects,
                    delete r.backgroundImage,
                    delete r.overlayImage,
                    delete r.background,
                    delete r.overlay,
                    n._setOptions(r),
                    n.renderAll(),
                    e && e();
                });
            },
            i
          ),
          this
        );
      }
    },
    _setBgOverlay: function(t, e) {
      var i = {
        backgroundColor: !1,
        overlayColor: !1,
        backgroundImage: !1,
        overlayImage: !1,
      };
      if (t.backgroundImage || t.overlayImage || t.background || t.overlay) {
        var r = function() {
          i.backgroundImage &&
            i.overlayImage &&
            i.backgroundColor &&
            i.overlayColor &&
            e &&
            e();
        };
        this.__setBgOverlay('backgroundImage', t.backgroundImage, i, r),
          this.__setBgOverlay('overlayImage', t.overlayImage, i, r),
          this.__setBgOverlay('backgroundColor', t.background, i, r),
          this.__setBgOverlay('overlayColor', t.overlay, i, r);
      } else e && e();
    },
    __setBgOverlay: function(e, t, i, r) {
      var n = this;
      if (!t) return (i[e] = !0), void (r && r());
      'backgroundImage' === e || 'overlayImage' === e
        ? fabric.util.enlivenObjects([t], function(t) {
            (n[e] = t[0]), (i[e] = !0), r && r();
          })
        : this['set' + fabric.util.string.capitalize(e, !0)](t, function() {
            (i[e] = !0), r && r();
          });
    },
    _enlivenObjects: function(t, e, i) {
      t && 0 !== t.length
        ? fabric.util.enlivenObjects(
            t,
            function(t) {
              e && e(t);
            },
            null,
            i
          )
        : e && e([]);
    },
    _toDataURL: function(e, i) {
      this.clone(function(t) {
        i(t.toDataURL(e));
      });
    },
    _toDataURLWithMultiplier: function(e, i, r) {
      this.clone(function(t) {
        r(t.toDataURLWithMultiplier(e, i));
      });
    },
    clone: function(e, t) {
      var i = JSON.stringify(this.toJSON(t));
      this.cloneWithoutData(function(t) {
        t.loadFromJSON(i, function() {
          e && e(t);
        });
      });
    },
    cloneWithoutData: function(t) {
      var e = fabric.util.createCanvasElement();
      (e.width = this.width), (e.height = this.height);
      var i = new fabric.Canvas(e);
      (i.clipTo = this.clipTo),
        this.backgroundImage
          ? (i.setBackgroundImage(this.backgroundImage.src, function() {
              i.renderAll(), t && t(i);
            }),
            (i.backgroundImageOpacity = this.backgroundImageOpacity),
            (i.backgroundImageStretch = this.backgroundImageStretch))
          : t && t(i);
    },
  }),
  (function(t) {
    'use strict';
    var x = t.fabric || (t.fabric = {}),
      e = x.util.object.extend,
      o = x.util.object.clone,
      r = x.util.toFixed,
      i = x.util.string.capitalize,
      a = x.util.degreesToRadians,
      n = x.StaticCanvas.supports('setLineDash'),
      s = !x.isLikelyNode;
    x.Object ||
      ((x.Object = x.util.createClass(x.CommonMethods, {
        type: 'object',
        originX: 'left',
        originY: 'top',
        top: 0,
        left: 0,
        width: 0,
        height: 0,
        scaleX: 1,
        scaleY: 1,
        flipX: !1,
        flipY: !1,
        opacity: 1,
        angle: 0,
        skewX: 0,
        skewY: 0,
        cornerSize: 13,
        transparentCorners: !0,
        hoverCursor: null,
        moveCursor: null,
        padding: 0,
        borderColor: 'rgba(102,153,255,0.75)',
        borderDashArray: null,
        cornerColor: 'rgba(102,153,255,0.5)',
        cornerStrokeColor: null,
        cornerStyle: 'rect',
        cornerDashArray: null,
        centeredScaling: !1,
        centeredRotation: !0,
        fill: 'rgb(0,0,0)',
        fillRule: 'nonzero',
        globalCompositeOperation: 'source-over',
        backgroundColor: '',
        selectionBackgroundColor: '',
        stroke: null,
        strokeWidth: 1,
        strokeDashArray: null,
        strokeDashOffset: 0,
        strokeLineCap: 'butt',
        strokeLineJoin: 'miter',
        strokeMiterLimit: 4,
        shadow: null,
        borderOpacityWhenMoving: 0.4,
        borderScaleFactor: 1,
        transformMatrix: null,
        minScaleLimit: 0,
        selectable: !0,
        evented: !0,
        visible: !0,
        hasControls: !0,
        hasBorders: !0,
        hasRotatingPoint: !0,
        rotatingPointOffset: 40,
        perPixelTargetFind: !1,
        includeDefaultValues: !0,
        clipTo: null,
        lockMovementX: !1,
        lockMovementY: !1,
        lockRotation: !1,
        lockScalingX: !1,
        lockScalingY: !1,
        lockUniScaling: !1,
        lockSkewingX: !1,
        lockSkewingY: !1,
        lockScalingFlip: !1,
        excludeFromExport: !1,
        objectCaching: s,
        statefullCache: !1,
        noScaleCache: !0,
        dirty: !0,
        __corner: 0,
        paintFirst: 'fill',
        stateProperties: 'top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor skewX skewY fillRule paintFirst clipPath'.split(
          ' '
        ),
        cacheProperties: 'fill stroke strokeWidth strokeDashArray width height paintFirst strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit backgroundColor clipPath'.split(
          ' '
        ),
        clipPath: void 0,
        inverted: !1,
        absolutePositioned: !1,
        initialize: function(t) {
          t && this.setOptions(t);
        },
        _createCacheCanvas: function() {
          (this._cacheProperties = {}),
            (this._cacheCanvas = x.util.createCanvasElement()),
            (this._cacheContext = this._cacheCanvas.getContext('2d')),
            this._updateCacheCanvas(),
            (this.dirty = !0);
        },
        _limitCacheSize: function(t) {
          var e = x.perfLimitSizeTotal,
            i = t.width,
            r = t.height,
            n = x.maxCacheSideLimit,
            s = x.minCacheSideLimit;
          if (i <= n && r <= n && i * r <= e)
            return i < s && (t.width = s), r < s && (t.height = s), t;
          var o = i / r,
            a = x.util.limitDimsByArea(o, e),
            h = x.util.capValue,
            c = h(s, a.x, n),
            l = h(s, a.y, n);
          return (
            c < i && ((t.zoomX /= i / c), (t.width = c), (t.capped = !0)),
            l < r && ((t.zoomY /= r / l), (t.height = l), (t.capped = !0)),
            t
          );
        },
        _getCacheCanvasDimensions: function() {
          var t = this.getTotalObjectScaling(),
            e = this._getNonTransformedDimensions(),
            i = t.scaleX,
            r = t.scaleY;
          return {
            width: e.x * i + 2,
            height: e.y * r + 2,
            zoomX: i,
            zoomY: r,
            x: e.x,
            y: e.y,
          };
        },
        _updateCacheCanvas: function() {
          var t = this.canvas;
          if (this.noScaleCache && t && t._currentTransform) {
            var e = t._currentTransform.target,
              i = t._currentTransform.action;
            if (this === e && i.slice && 'scale' === i.slice(0, 5)) return !1;
          }
          var r,
            n,
            s = this._cacheCanvas,
            o = this._limitCacheSize(this._getCacheCanvasDimensions()),
            a = x.minCacheSideLimit,
            h = o.width,
            c = o.height,
            l = o.zoomX,
            u = o.zoomY,
            f = h !== this.cacheWidth || c !== this.cacheHeight,
            d = this.zoomX !== l || this.zoomY !== u,
            g = f || d,
            p = 0,
            v = 0,
            m = !1;
          if (f) {
            var b = this._cacheCanvas.width,
              _ = this._cacheCanvas.height,
              y = b < h || _ < c;
            (m = y || ((h < 0.9 * b || c < 0.9 * _) && a < b && a < _)),
              y &&
                !o.capped &&
                (a < h || a < c) &&
                ((p = 0.1 * h), (v = 0.1 * c));
          }
          return (
            !!g &&
            (m
              ? ((s.width = Math.ceil(h + p)), (s.height = Math.ceil(c + v)))
              : (this._cacheContext.setTransform(1, 0, 0, 1, 0, 0),
                this._cacheContext.clearRect(0, 0, s.width, s.height)),
            (r = (o.x * l) / 2),
            (n = (o.y * u) / 2),
            (this.cacheTranslationX = Math.round(s.width / 2 - r) + r),
            (this.cacheTranslationY = Math.round(s.height / 2 - n) + n),
            (this.cacheWidth = h),
            (this.cacheHeight = c),
            this._cacheContext.translate(
              this.cacheTranslationX,
              this.cacheTranslationY
            ),
            this._cacheContext.scale(l, u),
            (this.zoomX = l),
            (this.zoomY = u),
            !0)
          );
        },
        setOptions: function(t) {
          this._setOptions(t),
            this._initGradient(t.fill, 'fill'),
            this._initGradient(t.stroke, 'stroke'),
            this._initClipping(t),
            this._initPattern(t.fill, 'fill'),
            this._initPattern(t.stroke, 'stroke');
        },
        transform: function(t) {
          var e;
          (e =
            this.group && !this.group._transformDone
              ? this.calcTransformMatrix()
              : this.calcOwnMatrix()),
            t.transform(e[0], e[1], e[2], e[3], e[4], e[5]);
        },
        toObject: function(t) {
          var e = x.Object.NUM_FRACTION_DIGITS,
            i = {
              type: this.type,
              version: x.version,
              originX: this.originX,
              originY: this.originY,
              left: r(this.left, e),
              top: r(this.top, e),
              width: r(this.width, e),
              height: r(this.height, e),
              fill:
                this.fill && this.fill.toObject
                  ? this.fill.toObject()
                  : this.fill,
              stroke:
                this.stroke && this.stroke.toObject
                  ? this.stroke.toObject()
                  : this.stroke,
              strokeWidth: r(this.strokeWidth, e),
              strokeDashArray: this.strokeDashArray
                ? this.strokeDashArray.concat()
                : this.strokeDashArray,
              strokeLineCap: this.strokeLineCap,
              strokeDashOffset: this.strokeDashOffset,
              strokeLineJoin: this.strokeLineJoin,
              strokeMiterLimit: r(this.strokeMiterLimit, e),
              scaleX: r(this.scaleX, e),
              scaleY: r(this.scaleY, e),
              angle: r(this.angle, e),
              flipX: this.flipX,
              flipY: this.flipY,
              opacity: r(this.opacity, e),
              shadow:
                this.shadow && this.shadow.toObject
                  ? this.shadow.toObject()
                  : this.shadow,
              visible: this.visible,
              clipTo: this.clipTo && String(this.clipTo),
              backgroundColor: this.backgroundColor,
              fillRule: this.fillRule,
              paintFirst: this.paintFirst,
              globalCompositeOperation: this.globalCompositeOperation,
              transformMatrix: this.transformMatrix
                ? this.transformMatrix.concat()
                : null,
              skewX: r(this.skewX, e),
              skewY: r(this.skewY, e),
            };
          return (
            this.clipPath &&
              ((i.clipPath = this.clipPath.toObject(t)),
              (i.clipPath.inverted = this.clipPath.inverted),
              (i.clipPath.absolutePositioned = this.clipPath.absolutePositioned)),
            x.util.populateWithProperties(this, i, t),
            this.includeDefaultValues || (i = this._removeDefaultValues(i)),
            i
          );
        },
        toDatalessObject: function(t) {
          return this.toObject(t);
        },
        _removeDefaultValues: function(e) {
          var i = x.util.getKlass(e.type).prototype;
          return (
            i.stateProperties.forEach(function(t) {
              e[t] === i[t] && delete e[t],
                '[object Array]' === Object.prototype.toString.call(e[t]) &&
                  '[object Array]' === Object.prototype.toString.call(i[t]) &&
                  0 === e[t].length &&
                  0 === i[t].length &&
                  delete e[t];
            }),
            e
          );
        },
        toString: function() {
          return '#<fabric.' + i(this.type) + '>';
        },
        getObjectScaling: function() {
          var t = this.scaleX,
            e = this.scaleY;
          if (this.group) {
            var i = this.group.getObjectScaling();
            (t *= i.scaleX), (e *= i.scaleY);
          }
          return { scaleX: t, scaleY: e };
        },
        getTotalObjectScaling: function() {
          var t = this.getObjectScaling(),
            e = t.scaleX,
            i = t.scaleY;
          if (this.canvas) {
            var r = this.canvas.getZoom(),
              n = this.canvas.getRetinaScaling();
            (e *= r * n), (i *= r * n);
          }
          return { scaleX: e, scaleY: i };
        },
        getObjectOpacity: function() {
          var t = this.opacity;
          return this.group && (t *= this.group.getObjectOpacity()), t;
        },
        _set: function(t, e) {
          var i = 'scaleX' === t || 'scaleY' === t,
            r = this[t] !== e,
            n = !1;
          return (
            i && (e = this._constrainScale(e)),
            'scaleX' === t && e < 0
              ? ((this.flipX = !this.flipX), (e *= -1))
              : 'scaleY' === t && e < 0
              ? ((this.flipY = !this.flipY), (e *= -1))
              : 'shadow' !== t || !e || e instanceof x.Shadow
              ? 'dirty' === t && this.group && this.group.set('dirty', e)
              : (e = new x.Shadow(e)),
            (this[t] = e),
            r &&
              ((n = this.group && this.group.isOnACache()),
              -1 < this.cacheProperties.indexOf(t)
                ? ((this.dirty = !0), n && this.group.set('dirty', !0))
                : n &&
                  -1 < this.stateProperties.indexOf(t) &&
                  this.group.set('dirty', !0)),
            this
          );
        },
        setOnGroup: function() {},
        getViewportTransform: function() {
          return this.canvas && this.canvas.viewportTransform
            ? this.canvas.viewportTransform
            : x.iMatrix.concat();
        },
        isNotVisible: function() {
          return (
            0 === this.opacity ||
            (0 === this.width && 0 === this.height && 0 === this.strokeWidth) ||
            !this.visible
          );
        },
        render: function(t) {
          this.isNotVisible() ||
            (this.canvas &&
              this.canvas.skipOffscreen &&
              !this.group &&
              !this.isOnScreen()) ||
            (t.save(),
            this._setupCompositeOperation(t),
            this.drawSelectionBackground(t),
            this.transform(t),
            this._setOpacity(t),
            this._setShadow(t, this),
            this.transformMatrix && t.transform.apply(t, this.transformMatrix),
            this.clipTo && x.util.clipContext(this, t),
            this.shouldCache()
              ? (this.renderCache(), this.drawCacheOnCanvas(t))
              : (this._removeCacheCanvas(),
                (this.dirty = !1),
                this.drawObject(t),
                this.objectCaching &&
                  this.statefullCache &&
                  this.saveState({ propertySet: 'cacheProperties' })),
            this.clipTo && t.restore(),
            t.restore());
        },
        renderCache: function(t) {
          (t = t || {}),
            this._cacheCanvas || this._createCacheCanvas(),
            this.isCacheDirty() &&
              (this.statefullCache &&
                this.saveState({ propertySet: 'cacheProperties' }),
              this.drawObject(this._cacheContext, t.forClipping),
              (this.dirty = !1));
        },
        _removeCacheCanvas: function() {
          (this._cacheCanvas = null),
            (this.cacheWidth = 0),
            (this.cacheHeight = 0);
        },
        needsItsOwnCache: function() {
          return (
            ('stroke' === this.paintFirst && 'object' == typeof this.shadow) ||
            !!this.clipPath
          );
        },
        shouldCache: function() {
          return (
            (this.ownCaching =
              this.objectCaching &&
              (!this.group ||
                this.needsItsOwnCache() ||
                !this.group.isOnACache())),
            this.ownCaching
          );
        },
        willDrawShadow: function() {
          return (
            !!this.shadow &&
            (0 !== this.shadow.offsetX || 0 !== this.shadow.offsetY)
          );
        },
        drawClipPathOnCache: function(t) {
          var e = this.clipPath;
          if (
            (t.save(),
            e.inverted
              ? (t.globalCompositeOperation = 'destination-out')
              : (t.globalCompositeOperation = 'destination-in'),
            e.absolutePositioned)
          ) {
            var i = x.util.invertTransform(this.calcTransformMatrix());
            t.transform(i[0], i[1], i[2], i[3], i[4], i[5]);
          }
          e.transform(t),
            t.scale(1 / e.zoomX, 1 / e.zoomY),
            t.drawImage(
              e._cacheCanvas,
              -e.cacheTranslationX,
              -e.cacheTranslationY
            ),
            t.restore();
        },
        drawObject: function(t, e) {
          e
            ? this._setClippingProperties(t)
            : (this._renderBackground(t),
              this._setStrokeStyles(t, this),
              this._setFillStyles(t, this)),
            this._render(t),
            this._drawClipPath(t);
        },
        _drawClipPath: function(t) {
          var e = this.clipPath;
          e &&
            ((e.canvas = this.canvas),
            e.shouldCache(),
            (e._transformDone = !0),
            e.renderCache({ forClipping: !0 }),
            this.drawClipPathOnCache(t));
        },
        drawCacheOnCanvas: function(t) {
          t.scale(1 / this.zoomX, 1 / this.zoomY),
            t.drawImage(
              this._cacheCanvas,
              -this.cacheTranslationX,
              -this.cacheTranslationY
            );
        },
        isCacheDirty: function(t) {
          if (this.isNotVisible()) return !1;
          if (this._cacheCanvas && !t && this._updateCacheCanvas()) return !0;
          if (
            this.dirty ||
            (this.clipPath && this.clipPath.absolutePositioned) ||
            (this.statefullCache && this.hasStateChanged('cacheProperties'))
          ) {
            if (this._cacheCanvas && !t) {
              var e = this.cacheWidth / this.zoomX,
                i = this.cacheHeight / this.zoomY;
              this._cacheContext.clearRect(-e / 2, -i / 2, e, i);
            }
            return !0;
          }
          return !1;
        },
        _renderBackground: function(t) {
          if (this.backgroundColor) {
            var e = this._getNonTransformedDimensions();
            (t.fillStyle = this.backgroundColor),
              t.fillRect(-e.x / 2, -e.y / 2, e.x, e.y),
              this._removeShadow(t);
          }
        },
        _setOpacity: function(t) {
          this.group && !this.group._transformDone
            ? (t.globalAlpha = this.getObjectOpacity())
            : (t.globalAlpha *= this.opacity);
        },
        _setStrokeStyles: function(t, e) {
          e.stroke &&
            ((t.lineWidth = e.strokeWidth),
            (t.lineCap = e.strokeLineCap),
            (t.lineDashOffset = e.strokeDashOffset),
            (t.lineJoin = e.strokeLineJoin),
            (t.miterLimit = e.strokeMiterLimit),
            (t.strokeStyle = e.stroke.toLive
              ? e.stroke.toLive(t, this)
              : e.stroke));
        },
        _setFillStyles: function(t, e) {
          e.fill &&
            (t.fillStyle = e.fill.toLive ? e.fill.toLive(t, this) : e.fill);
        },
        _setClippingProperties: function(t) {
          (t.globalAlpha = 1),
            (t.strokeStyle = 'transparent'),
            (t.fillStyle = '#000000');
        },
        _setLineDash: function(t, e, i) {
          e &&
            (1 & e.length && e.push.apply(e, e),
            n ? t.setLineDash(e) : i && i(t));
        },
        _renderControls: function(t, e) {
          var i,
            r,
            n,
            s = this.getViewportTransform(),
            o = this.calcTransformMatrix();
          (r =
            void 0 !== (e = e || {}).hasBorders
              ? e.hasBorders
              : this.hasBorders),
            (n = void 0 !== e.hasControls ? e.hasControls : this.hasControls),
            (o = x.util.multiplyTransformMatrices(s, o)),
            (i = x.util.qrDecompose(o)),
            t.save(),
            t.translate(i.translateX, i.translateY),
            (t.lineWidth = 1 * this.borderScaleFactor),
            this.group ||
              (t.globalAlpha = this.isMoving
                ? this.borderOpacityWhenMoving
                : 1),
            e.forActiveSelection
              ? (t.rotate(a(i.angle)), r && this.drawBordersInGroup(t, i, e))
              : (t.rotate(a(this.angle)), r && this.drawBorders(t, e)),
            n && this.drawControls(t, e),
            t.restore();
        },
        _setShadow: function(t) {
          if (this.shadow) {
            var e = (this.canvas && this.canvas.viewportTransform[0]) || 1,
              i = (this.canvas && this.canvas.viewportTransform[3]) || 1,
              r = this.getObjectScaling();
            this.canvas &&
              this.canvas._isRetinaScaling() &&
              ((e *= x.devicePixelRatio), (i *= x.devicePixelRatio)),
              (t.shadowColor = this.shadow.color),
              (t.shadowBlur =
                (this.shadow.blur *
                  x.browserShadowBlurConstant *
                  (e + i) *
                  (r.scaleX + r.scaleY)) /
                4),
              (t.shadowOffsetX = this.shadow.offsetX * e * r.scaleX),
              (t.shadowOffsetY = this.shadow.offsetY * i * r.scaleY);
          }
        },
        _removeShadow: function(t) {
          this.shadow &&
            ((t.shadowColor = ''),
            (t.shadowBlur = t.shadowOffsetX = t.shadowOffsetY = 0));
        },
        _applyPatternGradientTransform: function(t, e) {
          if (!e || !e.toLive) return { offsetX: 0, offsetY: 0 };
          var i = e.gradientTransform || e.patternTransform,
            r = -this.width / 2 + e.offsetX || 0,
            n = -this.height / 2 + e.offsetY || 0;
          return (
            t.translate(r, n),
            i && t.transform(i[0], i[1], i[2], i[3], i[4], i[5]),
            { offsetX: r, offsetY: n }
          );
        },
        _renderPaintInOrder: function(t) {
          'stroke' === this.paintFirst
            ? (this._renderStroke(t), this._renderFill(t))
            : (this._renderFill(t), this._renderStroke(t));
        },
        _renderFill: function(t) {
          this.fill &&
            (t.save(),
            this._applyPatternGradientTransform(t, this.fill),
            'evenodd' === this.fillRule ? t.fill('evenodd') : t.fill(),
            t.restore());
        },
        _renderStroke: function(t) {
          this.stroke &&
            0 !== this.strokeWidth &&
            (this.shadow && !this.shadow.affectStroke && this._removeShadow(t),
            t.save(),
            this._setLineDash(
              t,
              this.strokeDashArray,
              this._renderDashedStroke
            ),
            this._applyPatternGradientTransform(t, this.stroke),
            t.stroke(),
            t.restore());
        },
        _findCenterFromElement: function() {
          return {
            x: this.left + this.width / 2,
            y: this.top + this.height / 2,
          };
        },
        _assignTransformMatrixProps: function() {
          if (this.transformMatrix) {
            var t = x.util.qrDecompose(this.transformMatrix);
            (this.flipX = !1),
              (this.flipY = !1),
              this.set('scaleX', t.scaleX),
              this.set('scaleY', t.scaleY),
              (this.angle = t.angle),
              (this.skewX = t.skewX),
              (this.skewY = 0);
          }
        },
        _removeTransformMatrix: function(t) {
          var e = this._findCenterFromElement();
          this.transformMatrix &&
            (this._assignTransformMatrixProps(),
            (e = x.util.transformPoint(e, this.transformMatrix))),
            (this.transformMatrix = null),
            t &&
              ((this.scaleX *= t.scaleX),
              (this.scaleY *= t.scaleY),
              (this.cropX = t.cropX),
              (this.cropY = t.cropY),
              (e.x += t.offsetLeft),
              (e.y += t.offsetTop),
              (this.width = t.width),
              (this.height = t.height)),
            this.setPositionByOrigin(e, 'center', 'center');
        },
        clone: function(t, e) {
          var i = this.toObject(e);
          this.constructor.fromObject
            ? this.constructor.fromObject(i, t)
            : x.Object._fromObject('Object', i, t);
        },
        cloneAsImage: function(e, t) {
          var i = this.toDataURL(t);
          return (
            x.util.loadImage(i, function(t) {
              e && e(new x.Image(t));
            }),
            this
          );
        },
        toDataURL: function(t) {
          t || (t = {});
          var e = x.util,
            i = e.saveObjectTransform(this),
            r = this.shadow,
            n = Math.abs;
          t.withoutTransform && e.resetObjectTransform(this),
            t.withoutShadow && (this.shadow = null);
          var s,
            o,
            a = x.util.createCanvasElement(),
            h = this.getBoundingRect(!0, !0),
            c = this.shadow,
            l = { x: 0, y: 0 };
          c &&
            ((o = c.blur),
            (s = this.getObjectScaling()),
            (l.x = 2 * Math.round((n(c.offsetX) + o) * n(s.scaleX))),
            (l.y = 2 * Math.round((n(c.offsetY) + o) * n(s.scaleY)))),
            (a.width = h.width + l.x),
            (a.height = h.height + l.y),
            (a.width += a.width % 2 ? 2 - (a.width % 2) : 0),
            (a.height += a.height % 2 ? 2 - (a.height % 2) : 0);
          var u = new x.StaticCanvas(a, {
            enableRetinaScaling: t.enableRetinaScaling,
            renderOnAddRemove: !1,
            skipOffscreen: !1,
          });
          'jpeg' === t.format && (u.backgroundColor = '#fff'),
            this.setPositionByOrigin(
              new x.Point(u.width / 2, u.height / 2),
              'center',
              'center'
            );
          var f = this.canvas;
          u.add(this);
          var d = u.toDataURL(t);
          return (
            (this.shadow = r),
            this.set(i).setCoords(),
            (this.canvas = f),
            (u._objects = []),
            u.dispose(),
            (u = null),
            d
          );
        },
        isType: function(t) {
          return this.type === t;
        },
        complexity: function() {
          return 1;
        },
        toJSON: function(t) {
          return this.toObject(t);
        },
        setGradient: function(t, e) {
          e || (e = {});
          var i = { colorStops: [] };
          return (
            (i.type = e.type || (e.r1 || e.r2 ? 'radial' : 'linear')),
            (i.coords = { x1: e.x1, y1: e.y1, x2: e.x2, y2: e.y2 }),
            (e.r1 || e.r2) && ((i.coords.r1 = e.r1), (i.coords.r2 = e.r2)),
            (i.gradientTransform = e.gradientTransform),
            x.Gradient.prototype.addColorStop.call(i, e.colorStops),
            this.set(t, x.Gradient.forObject(this, i))
          );
        },
        setPatternFill: function(t, e) {
          return this.set('fill', new x.Pattern(t, e));
        },
        setShadow: function(t) {
          return this.set('shadow', t ? new x.Shadow(t) : null);
        },
        setColor: function(t) {
          return this.set('fill', t), this;
        },
        rotate: function(t) {
          var e =
            ('center' !== this.originX || 'center' !== this.originY) &&
            this.centeredRotation;
          return (
            e && this._setOriginToCenter(),
            this.set('angle', t),
            e && this._resetOrigin(),
            this
          );
        },
        centerH: function() {
          return this.canvas && this.canvas.centerObjectH(this), this;
        },
        viewportCenterH: function() {
          return this.canvas && this.canvas.viewportCenterObjectH(this), this;
        },
        centerV: function() {
          return this.canvas && this.canvas.centerObjectV(this), this;
        },
        viewportCenterV: function() {
          return this.canvas && this.canvas.viewportCenterObjectV(this), this;
        },
        center: function() {
          return this.canvas && this.canvas.centerObject(this), this;
        },
        viewportCenter: function() {
          return this.canvas && this.canvas.viewportCenterObject(this), this;
        },
        getLocalPointer: function(t, e) {
          e = e || this.canvas.getPointer(t);
          var i = new x.Point(e.x, e.y),
            r = this._getLeftTopCoords();
          return (
            this.angle && (i = x.util.rotatePoint(i, r, a(-this.angle))),
            { x: i.x - r.x, y: i.y - r.y }
          );
        },
        _setupCompositeOperation: function(t) {
          this.globalCompositeOperation &&
            (t.globalCompositeOperation = this.globalCompositeOperation);
        },
      })),
      x.util.createAccessors && x.util.createAccessors(x.Object),
      e(x.Object.prototype, x.Observable),
      (x.Object.NUM_FRACTION_DIGITS = 2),
      (x.Object._fromObject = function(t, i, r, n) {
        var s = x[t];
        (i = o(i, !0)),
          x.util.enlivenPatterns([i.fill, i.stroke], function(t) {
            void 0 !== t[0] && (i.fill = t[0]),
              void 0 !== t[1] && (i.stroke = t[1]),
              x.util.enlivenObjects([i.clipPath], function(t) {
                i.clipPath = t[0];
                var e = n ? new s(i[n], i) : new s(i);
                r && r(e);
              });
          });
      }),
      (x.Object.__uid = 0));
  })('undefined' != typeof exports ? exports : this),
  (function() {
    var a = fabric.util.degreesToRadians,
      l = { left: -0.5, center: 0, right: 0.5 },
      u = { top: -0.5, center: 0, bottom: 0.5 };
    fabric.util.object.extend(fabric.Object.prototype, {
      translateToGivenOrigin: function(t, e, i, r, n) {
        var s,
          o,
          a,
          h = t.x,
          c = t.y;
        return (
          'string' == typeof e ? (e = l[e]) : (e -= 0.5),
          'string' == typeof r ? (r = l[r]) : (r -= 0.5),
          'string' == typeof i ? (i = u[i]) : (i -= 0.5),
          'string' == typeof n ? (n = u[n]) : (n -= 0.5),
          (o = n - i),
          ((s = r - e) || o) &&
            ((a = this._getTransformedDimensions()),
            (h = t.x + s * a.x),
            (c = t.y + o * a.y)),
          new fabric.Point(h, c)
        );
      },
      translateToCenterPoint: function(t, e, i) {
        var r = this.translateToGivenOrigin(t, e, i, 'center', 'center');
        return this.angle ? fabric.util.rotatePoint(r, t, a(this.angle)) : r;
      },
      translateToOriginPoint: function(t, e, i) {
        var r = this.translateToGivenOrigin(t, 'center', 'center', e, i);
        return this.angle ? fabric.util.rotatePoint(r, t, a(this.angle)) : r;
      },
      getCenterPoint: function() {
        var t = new fabric.Point(this.left, this.top);
        return this.translateToCenterPoint(t, this.originX, this.originY);
      },
      getPointByOrigin: function(t, e) {
        var i = this.getCenterPoint();
        return this.translateToOriginPoint(i, t, e);
      },
      toLocalPoint: function(t, e, i) {
        var r,
          n,
          s = this.getCenterPoint();
        return (
          (r =
            void 0 !== e && void 0 !== i
              ? this.translateToGivenOrigin(s, 'center', 'center', e, i)
              : new fabric.Point(this.left, this.top)),
          (n = new fabric.Point(t.x, t.y)),
          this.angle && (n = fabric.util.rotatePoint(n, s, -a(this.angle))),
          n.subtractEquals(r)
        );
      },
      setPositionByOrigin: function(t, e, i) {
        var r = this.translateToCenterPoint(t, e, i),
          n = this.translateToOriginPoint(r, this.originX, this.originY);
        this.set('left', n.x), this.set('top', n.y);
      },
      adjustPosition: function(t) {
        var e,
          i,
          r = a(this.angle),
          n = this.getScaledWidth(),
          s = fabric.util.cos(r) * n,
          o = fabric.util.sin(r) * n;
        (e =
          'string' == typeof this.originX
            ? l[this.originX]
            : this.originX - 0.5),
          (i = 'string' == typeof t ? l[t] : t - 0.5),
          (this.left += s * (i - e)),
          (this.top += o * (i - e)),
          this.setCoords(),
          (this.originX = t);
      },
      _setOriginToCenter: function() {
        (this._originalOriginX = this.originX),
          (this._originalOriginY = this.originY);
        var t = this.getCenterPoint();
        (this.originX = 'center'),
          (this.originY = 'center'),
          (this.left = t.x),
          (this.top = t.y);
      },
      _resetOrigin: function() {
        var t = this.translateToOriginPoint(
          this.getCenterPoint(),
          this._originalOriginX,
          this._originalOriginY
        );
        (this.originX = this._originalOriginX),
          (this.originY = this._originalOriginY),
          (this.left = t.x),
          (this.top = t.y),
          (this._originalOriginX = null),
          (this._originalOriginY = null);
      },
      _getLeftTopCoords: function() {
        return this.translateToOriginPoint(
          this.getCenterPoint(),
          'left',
          'top'
        );
      },
    });
  })(),
  (function() {
    var k = fabric.util.degreesToRadians,
      D = fabric.util.multiplyTransformMatrices,
      E = fabric.util.transformPoint;
    fabric.util.object.extend(fabric.Object.prototype, {
      oCoords: null,
      aCoords: null,
      ownMatrixCache: null,
      matrixCache: null,
      getCoords: function(t, e) {
        this.oCoords || this.setCoords();
        var i,
          r = t ? this.aCoords : this.oCoords;
        return (
          (i = e ? this.calcCoords(t) : r),
          [
            new fabric.Point(i.tl.x, i.tl.y),
            new fabric.Point(i.tr.x, i.tr.y),
            new fabric.Point(i.br.x, i.br.y),
            new fabric.Point(i.bl.x, i.bl.y),
          ]
        );
      },
      intersectsWithRect: function(t, e, i, r) {
        var n = this.getCoords(i, r);
        return (
          'Intersection' ===
          fabric.Intersection.intersectPolygonRectangle(n, t, e).status
        );
      },
      intersectsWithObject: function(t, e, i) {
        return (
          'Intersection' ===
            fabric.Intersection.intersectPolygonPolygon(
              this.getCoords(e, i),
              t.getCoords(e, i)
            ).status ||
          t.isContainedWithinObject(this, e, i) ||
          this.isContainedWithinObject(t, e, i)
        );
      },
      isContainedWithinObject: function(t, e, i) {
        for (
          var r = this.getCoords(e, i),
            n = 0,
            s = t._getImageLines(
              i ? t.calcCoords(e) : e ? t.aCoords : t.oCoords
            );
          n < 4;
          n++
        )
          if (!t.containsPoint(r[n], s)) return !1;
        return !0;
      },
      isContainedWithinRect: function(t, e, i, r) {
        var n = this.getBoundingRect(i, r);
        return (
          n.left >= t.x &&
          n.left + n.width <= e.x &&
          n.top >= t.y &&
          n.top + n.height <= e.y
        );
      },
      containsPoint: function(t, e, i, r) {
        e =
          e ||
          this._getImageLines(
            r ? this.calcCoords(i) : i ? this.aCoords : this.oCoords
          );
        var n = this._findCrossPoints(t, e);
        return 0 !== n && n % 2 == 1;
      },
      isOnScreen: function(t) {
        if (!this.canvas) return !1;
        for (
          var e,
            i = this.canvas.vptCoords.tl,
            r = this.canvas.vptCoords.br,
            n = this.getCoords(!0, t),
            s = 0;
          s < 4;
          s++
        )
          if ((e = n[s]).x <= r.x && e.x >= i.x && e.y <= r.y && e.y >= i.y)
            return !0;
        return (
          !!this.intersectsWithRect(i, r, !0, t) ||
          this._containsCenterOfCanvas(i, r, t)
        );
      },
      _containsCenterOfCanvas: function(t, e, i) {
        var r = { x: (t.x + e.x) / 2, y: (t.y + e.y) / 2 };
        return !!this.containsPoint(r, null, !0, i);
      },
      isPartiallyOnScreen: function(t) {
        if (!this.canvas) return !1;
        var e = this.canvas.vptCoords.tl,
          i = this.canvas.vptCoords.br;
        return (
          !!this.intersectsWithRect(e, i, !0, t) ||
          this._containsCenterOfCanvas(e, i, t)
        );
      },
      _getImageLines: function(t) {
        return {
          topline: { o: t.tl, d: t.tr },
          rightline: { o: t.tr, d: t.br },
          bottomline: { o: t.br, d: t.bl },
          leftline: { o: t.bl, d: t.tl },
        };
      },
      _findCrossPoints: function(t, e) {
        var i,
          r,
          n,
          s = 0;
        for (var o in e)
          if (
            !(
              ((n = e[o]).o.y < t.y && n.d.y < t.y) ||
              (n.o.y >= t.y && n.d.y >= t.y) ||
              (n.o.x === n.d.x && n.o.x >= t.x
                ? (r = n.o.x)
                : (0,
                  (i = (n.d.y - n.o.y) / (n.d.x - n.o.x)),
                  (r = -(t.y - 0 * t.x - (n.o.y - i * n.o.x)) / (0 - i))),
              r >= t.x && (s += 1),
              2 !== s)
            )
          )
            break;
        return s;
      },
      getBoundingRect: function(t, e) {
        var i = this.getCoords(t, e);
        return fabric.util.makeBoundingBoxFromPoints(i);
      },
      getScaledWidth: function() {
        return this._getTransformedDimensions().x;
      },
      getScaledHeight: function() {
        return this._getTransformedDimensions().y;
      },
      _constrainScale: function(t) {
        return Math.abs(t) < this.minScaleLimit
          ? t < 0
            ? -this.minScaleLimit
            : this.minScaleLimit
          : 0 === t
          ? 1e-4
          : t;
      },
      scale: function(t) {
        return this._set('scaleX', t), this._set('scaleY', t), this.setCoords();
      },
      scaleToWidth: function(t, e) {
        var i = this.getBoundingRect(e).width / this.getScaledWidth();
        return this.scale(t / this.width / i);
      },
      scaleToHeight: function(t, e) {
        var i = this.getBoundingRect(e).height / this.getScaledHeight();
        return this.scale(t / this.height / i);
      },
      calcCoords: function(t) {
        var e = this._calcRotateMatrix(),
          i = this._calcTranslateMatrix(),
          r = D(i, e),
          n = this.getViewportTransform(),
          s = t ? r : D(n, r),
          o = this._getTransformedDimensions(),
          a = o.x / 2,
          h = o.y / 2,
          c = E({ x: -a, y: -h }, s),
          l = E({ x: a, y: -h }, s),
          u = E({ x: -a, y: h }, s),
          f = E({ x: a, y: h }, s);
        if (!t) {
          var d = this.padding,
            g = k(this.angle),
            p = fabric.util.cos(g),
            v = fabric.util.sin(g),
            m = p * d,
            b = v * d,
            _ = m + b,
            y = m - b;
          d &&
            ((c.x -= y),
            (c.y -= _),
            (l.x += _),
            (l.y -= y),
            (u.x -= _),
            (u.y += y),
            (f.x += y),
            (f.y += _));
          var x = new fabric.Point((c.x + u.x) / 2, (c.y + u.y) / 2),
            C = new fabric.Point((l.x + c.x) / 2, (l.y + c.y) / 2),
            S = new fabric.Point((f.x + l.x) / 2, (f.y + l.y) / 2),
            T = new fabric.Point((f.x + u.x) / 2, (f.y + u.y) / 2),
            w = new fabric.Point(
              C.x + v * this.rotatingPointOffset,
              C.y - p * this.rotatingPointOffset
            );
        }
        var O = { tl: c, tr: l, br: f, bl: u };
        return (
          t || ((O.ml = x), (O.mt = C), (O.mr = S), (O.mb = T), (O.mtr = w)), O
        );
      },
      setCoords: function(t, e) {
        return (
          (this.oCoords = this.calcCoords(t)),
          e || (this.aCoords = this.calcCoords(!0)),
          t || (this._setCornerCoords && this._setCornerCoords()),
          this
        );
      },
      _calcRotateMatrix: function() {
        if (this.angle) {
          var t = k(this.angle),
            e = fabric.util.cos(t),
            i = fabric.util.sin(t);
          return [e, i, -i, e, 0, 0];
        }
        return fabric.iMatrix.concat();
      },
      _calcTranslateMatrix: function() {
        var t = this.getCenterPoint();
        return [1, 0, 0, 1, t.x, t.y];
      },
      transformMatrixKey: function(t) {
        var e = '_',
          i = '';
        return (
          !t && this.group && (i = this.group.transformMatrixKey(t) + e),
          i +
            this.top +
            e +
            this.left +
            e +
            this.scaleX +
            e +
            this.scaleY +
            e +
            this.skewX +
            e +
            this.skewY +
            e +
            this.angle +
            e +
            this.originX +
            e +
            this.originY +
            e +
            this.width +
            e +
            this.height +
            e +
            this.strokeWidth +
            this.flipX +
            this.flipY
        );
      },
      calcTransformMatrix: function(t) {
        if (t) return this.calcOwnMatrix();
        var e = this.transformMatrixKey(),
          i = this.matrixCache || (this.matrixCache = {});
        if (i.key === e) return i.value;
        var r = this.calcOwnMatrix();
        return (
          this.group && (r = D(this.group.calcTransformMatrix(), r)),
          (i.key = e),
          (i.value = r)
        );
      },
      calcOwnMatrix: function() {
        var t = this.transformMatrixKey(!0),
          e = this.ownMatrixCache || (this.ownMatrixCache = {});
        if (e.key === t) return e.value;
        var i,
          r = this._calcTranslateMatrix(),
          n = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, !0);
        return (
          this.angle && ((i = this._calcRotateMatrix()), (r = D(r, i))),
          (r = D(r, n)),
          (e.key = t),
          (e.value = r)
        );
      },
      _calcDimensionsTransformMatrix: function(t, e, i) {
        var r,
          n = [
            this.scaleX * (i && this.flipX ? -1 : 1),
            0,
            0,
            this.scaleY * (i && this.flipY ? -1 : 1),
            0,
            0,
          ];
        return (
          t && ((r = [1, 0, Math.tan(k(t)), 1]), (n = D(n, r, !0))),
          e && ((r = [1, Math.tan(k(e)), 0, 1]), (n = D(n, r, !0))),
          n
        );
      },
      _getNonTransformedDimensions: function() {
        var t = this.strokeWidth;
        return { x: this.width + t, y: this.height + t };
      },
      _getTransformedDimensions: function(t, e) {
        void 0 === t && (t = this.skewX), void 0 === e && (e = this.skewY);
        var i = this._getNonTransformedDimensions();
        if (0 === t && 0 === e)
          return { x: i.x * this.scaleX, y: i.y * this.scaleY };
        var r,
          n,
          s = i.x / 2,
          o = i.y / 2,
          a = [
            { x: -s, y: -o },
            { x: s, y: -o },
            { x: -s, y: o },
            { x: s, y: o },
          ],
          h = this._calcDimensionsTransformMatrix(t, e, !1);
        for (r = 0; r < a.length; r++)
          a[r] = fabric.util.transformPoint(a[r], h);
        return {
          x: (n = fabric.util.makeBoundingBoxFromPoints(a)).width,
          y: n.height,
        };
      },
      _calculateCurrentDimensions: function() {
        var t = this.getViewportTransform(),
          e = this._getTransformedDimensions();
        return fabric.util.transformPoint(e, t, !0).scalarAdd(2 * this.padding);
      },
    });
  })(),
  fabric.util.object.extend(fabric.Object.prototype, {
    sendToBack: function() {
      return (
        this.group
          ? fabric.StaticCanvas.prototype.sendToBack.call(this.group, this)
          : this.canvas.sendToBack(this),
        this
      );
    },
    bringToFront: function() {
      return (
        this.group
          ? fabric.StaticCanvas.prototype.bringToFront.call(this.group, this)
          : this.canvas.bringToFront(this),
        this
      );
    },
    sendBackwards: function(t) {
      return (
        this.group
          ? fabric.StaticCanvas.prototype.sendBackwards.call(
              this.group,
              this,
              t
            )
          : this.canvas.sendBackwards(this, t),
        this
      );
    },
    bringForward: function(t) {
      return (
        this.group
          ? fabric.StaticCanvas.prototype.bringForward.call(this.group, this, t)
          : this.canvas.bringForward(this, t),
        this
      );
    },
    moveTo: function(t) {
      return (
        this.group && 'activeSelection' !== this.group.type
          ? fabric.StaticCanvas.prototype.moveTo.call(this.group, this, t)
          : this.canvas.moveTo(this, t),
        this
      );
    },
  }),
  (function() {
    function f(t, e) {
      if (e) {
        if (e.toLive) return t + ': url(#SVGID_' + e.id + '); ';
        var i = new fabric.Color(e),
          r = t + ': ' + i.toRgb() + '; ',
          n = i.getAlpha();
        return 1 !== n && (r += t + '-opacity: ' + n.toString() + '; '), r;
      }
      return t + ': none; ';
    }
    var i = fabric.util.toFixed;
    fabric.util.object.extend(fabric.Object.prototype, {
      getSvgStyles: function(t) {
        var e = this.fillRule ? this.fillRule : 'nonzero',
          i = this.strokeWidth ? this.strokeWidth : '0',
          r = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none',
          n = this.strokeDashOffset ? this.strokeDashOffset : '0',
          s = this.strokeLineCap ? this.strokeLineCap : 'butt',
          o = this.strokeLineJoin ? this.strokeLineJoin : 'miter',
          a = this.strokeMiterLimit ? this.strokeMiterLimit : '4',
          h = void 0 !== this.opacity ? this.opacity : '1',
          c = this.visible ? '' : ' visibility: hidden;',
          l = t ? '' : this.getSvgFilter(),
          u = f('fill', this.fill);
        return [
          f('stroke', this.stroke),
          'stroke-width: ',
          i,
          '; ',
          'stroke-dasharray: ',
          r,
          '; ',
          'stroke-linecap: ',
          s,
          '; ',
          'stroke-dashoffset: ',
          n,
          '; ',
          'stroke-linejoin: ',
          o,
          '; ',
          'stroke-miterlimit: ',
          a,
          '; ',
          u,
          'fill-rule: ',
          e,
          '; ',
          'opacity: ',
          h,
          ';',
          l,
          c,
        ].join('');
      },
      getSvgSpanStyles: function(t, e) {
        var i = '; ',
          r = t.fontFamily
            ? 'font-family: ' +
              (-1 === t.fontFamily.indexOf("'") &&
              -1 === t.fontFamily.indexOf('"')
                ? "'" + t.fontFamily + "'"
                : t.fontFamily) +
              i
            : '',
          n = t.strokeWidth ? 'stroke-width: ' + t.strokeWidth + i : '',
          s = ((r = r),
          t.fontSize ? 'font-size: ' + t.fontSize + 'px' + i : ''),
          o = t.fontStyle ? 'font-style: ' + t.fontStyle + i : '',
          a = t.fontWeight ? 'font-weight: ' + t.fontWeight + i : '',
          h = t.fill ? f('fill', t.fill) : '',
          c = t.stroke ? f('stroke', t.stroke) : '',
          l = this.getSvgTextDecoration(t);
        return (
          l && (l = 'text-decoration: ' + l + i),
          [
            c,
            n,
            r,
            s,
            o,
            a,
            l,
            h,
            t.deltaY ? 'baseline-shift: ' + -t.deltaY + '; ' : '',
            e ? 'white-space: pre; ' : '',
          ].join('')
        );
      },
      getSvgTextDecoration: function(t) {
        return 'overline' in t || 'underline' in t || 'linethrough' in t
          ? (t.overline ? 'overline ' : '') +
              (t.underline ? 'underline ' : '') +
              (t.linethrough ? 'line-through ' : '')
          : '';
      },
      getSvgFilter: function() {
        return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : '';
      },
      getSvgCommons: function() {
        return [
          this.id ? 'id="' + this.id + '" ' : '',
          this.clipPath
            ? 'clip-path="url(#' + this.clipPath.clipPathId + ')" '
            : '',
        ].join('');
      },
      getSvgTransform: function(t, e) {
        return (
          'transform="matrix(' +
          (t ? this.calcTransformMatrix() : this.calcOwnMatrix())
            .map(function(t) {
              return i(t, fabric.Object.NUM_FRACTION_DIGITS);
            })
            .join(' ') +
          ')' +
          (e || '') +
          this.getSvgTransformMatrix() +
          '" '
        );
      },
      getSvgTransformMatrix: function() {
        return this.transformMatrix
          ? ' matrix(' + this.transformMatrix.join(' ') + ')'
          : '';
      },
      _setSVGBg: function(t) {
        if (this.backgroundColor) {
          var e = fabric.Object.NUM_FRACTION_DIGITS;
          t.push(
            '\t\t<rect ',
            this._getFillAttributes(this.backgroundColor),
            ' x="',
            i(-this.width / 2, e),
            '" y="',
            i(-this.height / 2, e),
            '" width="',
            i(this.width, e),
            '" height="',
            i(this.height, e),
            '"></rect>\n'
          );
        }
      },
      toSVG: function(t) {
        return this._createBaseSVGMarkup(this._toSVG(), { reviver: t });
      },
      toClipPathSVG: function(t) {
        return (
          '\t' +
          this._createBaseClipPathSVGMarkup(this._toSVG(), { reviver: t })
        );
      },
      _createBaseClipPathSVGMarkup: function(t, e) {
        var i = (e = e || {}).reviver,
          r = e.additionalTransform || '',
          n = [this.getSvgTransform(!0, r), this.getSvgCommons()].join(''),
          s = t.indexOf('COMMON_PARTS');
        return (t[s] = n), i ? i(t.join('')) : t.join('');
      },
      _createBaseSVGMarkup: function(t, e) {
        var i,
          r,
          n = (e = e || {}).noStyle,
          s = e.withShadow,
          o = e.reviver,
          a = n ? '' : 'style="' + this.getSvgStyles() + '" ',
          h = s ? 'style="' + this.getSvgFilter() + '" ' : '',
          c = this.clipPath,
          l = this.clipPath && this.clipPath.absolutePositioned,
          u = [],
          f = t.indexOf('COMMON_PARTS'),
          d = e.additionalTransform;
        return (
          c &&
            ((c.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++),
            (r =
              '<clipPath id="' +
              c.clipPathId +
              '" >\n' +
              this.clipPath.toClipPathSVG(o) +
              '</clipPath>\n')),
          l && u.push('<g ', h, this.getSvgCommons(), ' >\n'),
          u.push(
            '<g ',
            this.getSvgTransform(!1),
            l ? '' : h + this.getSvgCommons(),
            ' >\n'
          ),
          (i = [
            a,
            n ? '' : this.addPaintOrder(),
            ' ',
            d ? 'transform="' + d + '" ' : '',
          ].join('')),
          (t[f] = i),
          this.fill && this.fill.toLive && u.push(this.fill.toSVG(this, !1)),
          this.stroke &&
            this.stroke.toLive &&
            u.push(this.stroke.toSVG(this, !1)),
          this.shadow && u.push(this.shadow.toSVG(this)),
          c && u.push(r),
          u.push(t.join('')),
          u.push('</g>\n'),
          l && u.push('</g>\n'),
          o ? o(u.join('')) : u.join('')
        );
      },
      addPaintOrder: function() {
        return 'fill' !== this.paintFirst
          ? ' paint-order="' + this.paintFirst + '" '
          : '';
      },
    });
  })(),
  (function() {
    var n = fabric.util.object.extend,
      r = 'stateProperties';
    function s(e, t, i) {
      var r = {};
      i.forEach(function(t) {
        r[t] = e[t];
      }),
        n(e[t], r, !0);
    }
    fabric.util.object.extend(fabric.Object.prototype, {
      hasStateChanged: function(t) {
        var e = '_' + (t = t || r);
        return (
          Object.keys(this[e]).length < this[t].length ||
          !(function t(e, i, r) {
            if (e === i) return !0;
            if (Array.isArray(e)) {
              if (!Array.isArray(i) || e.length !== i.length) return !1;
              for (var n = 0, s = e.length; n < s; n++)
                if (!t(e[n], i[n])) return !1;
              return !0;
            }
            if (e && 'object' == typeof e) {
              var o,
                a = Object.keys(e);
              if (
                !i ||
                'object' != typeof i ||
                (!r && a.length !== Object.keys(i).length)
              )
                return !1;
              for (n = 0, s = a.length; n < s; n++)
                if ('canvas' !== (o = a[n]) && !t(e[o], i[o])) return !1;
              return !0;
            }
          })(this[e], this, !0)
        );
      },
      saveState: function(t) {
        var e = (t && t.propertySet) || r,
          i = '_' + e;
        return this[i]
          ? (s(this, i, this[e]),
            t && t.stateProperties && s(this, i, t.stateProperties),
            this)
          : this.setupState(t);
      },
      setupState: function(t) {
        var e = (t = t || {}).propertySet || r;
        return (this['_' + (t.propertySet = e)] = {}), this.saveState(t), this;
      },
    });
  })(),
  (function() {
    var h = fabric.util.degreesToRadians;
    fabric.util.object.extend(fabric.Object.prototype, {
      _controlsVisibility: null,
      _findTargetCorner: function(t) {
        if (
          !this.hasControls ||
          this.group ||
          !this.canvas ||
          this.canvas._activeObject !== this
        )
          return !1;
        var e,
          i,
          r = t.x,
          n = t.y;
        for (var s in ((this.__corner = 0), this.oCoords))
          if (
            this.isControlVisible(s) &&
            ('mtr' !== s || this.hasRotatingPoint) &&
            (!this.get('lockUniScaling') ||
              ('mt' !== s && 'mr' !== s && 'mb' !== s && 'ml' !== s)) &&
            ((i = this._getImageLines(this.oCoords[s].corner)),
            0 !== (e = this._findCrossPoints({ x: r, y: n }, i)) && e % 2 == 1)
          )
            return (this.__corner = s);
        return !1;
      },
      _setCornerCoords: function() {
        var t,
          e,
          i = this.oCoords,
          r = h(45 - this.angle),
          n = 0.707106 * this.cornerSize,
          s = n * fabric.util.cos(r),
          o = n * fabric.util.sin(r);
        for (var a in i)
          (t = i[a].x),
            (e = i[a].y),
            (i[a].corner = {
              tl: { x: t - o, y: e - s },
              tr: { x: t + s, y: e - o },
              bl: { x: t - s, y: e + o },
              br: { x: t + o, y: e + s },
            });
      },
      drawSelectionBackground: function(t) {
        if (
          !this.selectionBackgroundColor ||
          (this.canvas && !this.canvas.interactive) ||
          (this.canvas && this.canvas._activeObject !== this)
        )
          return this;
        t.save();
        var e = this.getCenterPoint(),
          i = this._calculateCurrentDimensions(),
          r = this.canvas.viewportTransform;
        return (
          t.translate(e.x, e.y),
          t.scale(1 / r[0], 1 / r[3]),
          t.rotate(h(this.angle)),
          (t.fillStyle = this.selectionBackgroundColor),
          t.fillRect(-i.x / 2, -i.y / 2, i.x, i.y),
          t.restore(),
          this
        );
      },
      drawBorders: function(t, e) {
        e = e || {};
        var i = this._calculateCurrentDimensions(),
          r = 1 / this.borderScaleFactor,
          n = i.x + r,
          s = i.y + r,
          o =
            void 0 !== e.hasRotatingPoint
              ? e.hasRotatingPoint
              : this.hasRotatingPoint,
          a = void 0 !== e.hasControls ? e.hasControls : this.hasControls,
          h =
            void 0 !== e.rotatingPointOffset
              ? e.rotatingPointOffset
              : this.rotatingPointOffset;
        if (
          (t.save(),
          (t.strokeStyle = e.borderColor || this.borderColor),
          this._setLineDash(t, e.borderDashArray || this.borderDashArray, null),
          t.strokeRect(-n / 2, -s / 2, n, s),
          o && this.isControlVisible('mtr') && a)
        ) {
          var c = -s / 2;
          t.beginPath(), t.moveTo(0, c), t.lineTo(0, c - h), t.stroke();
        }
        return t.restore(), this;
      },
      drawBordersInGroup: function(t, e, i) {
        i = i || {};
        var r = this._getNonTransformedDimensions(),
          n = fabric.util.customTransformMatrix(e.scaleX, e.scaleY, e.skewX),
          s = fabric.util.transformPoint(r, n),
          o = 1 / this.borderScaleFactor,
          a = s.x + o,
          h = s.y + o;
        return (
          t.save(),
          this._setLineDash(t, i.borderDashArray || this.borderDashArray, null),
          (t.strokeStyle = i.borderColor || this.borderColor),
          t.strokeRect(-a / 2, -h / 2, a, h),
          t.restore(),
          this
        );
      },
      drawControls: function(t, e) {
        e = e || {};
        var i = this._calculateCurrentDimensions(),
          r = i.x,
          n = i.y,
          s = e.cornerSize || this.cornerSize,
          o = -(r + s) / 2,
          a = -(n + s) / 2,
          h =
            void 0 !== e.transparentCorners
              ? e.transparentCorners
              : this.transparentCorners,
          c =
            void 0 !== e.hasRotatingPoint
              ? e.hasRotatingPoint
              : this.hasRotatingPoint,
          l = h ? 'stroke' : 'fill';
        return (
          t.save(),
          (t.strokeStyle = t.fillStyle = e.cornerColor || this.cornerColor),
          this.transparentCorners ||
            (t.strokeStyle = e.cornerStrokeColor || this.cornerStrokeColor),
          this._setLineDash(t, e.cornerDashArray || this.cornerDashArray, null),
          this._drawControl('tl', t, l, o, a, e),
          this._drawControl('tr', t, l, o + r, a, e),
          this._drawControl('bl', t, l, o, a + n, e),
          this._drawControl('br', t, l, o + r, a + n, e),
          this.get('lockUniScaling') ||
            (this._drawControl('mt', t, l, o + r / 2, a, e),
            this._drawControl('mb', t, l, o + r / 2, a + n, e),
            this._drawControl('mr', t, l, o + r, a + n / 2, e),
            this._drawControl('ml', t, l, o, a + n / 2, e)),
          c &&
            this._drawControl(
              'mtr',
              t,
              l,
              o + r / 2,
              a - this.rotatingPointOffset,
              e
            ),
          t.restore(),
          this
        );
      },
      _drawControl: function(t, e, i, r, n, s) {
        if (((s = s || {}), this.isControlVisible(t))) {
          var o = this.cornerSize,
            a = !this.transparentCorners && this.cornerStrokeColor;
          switch (s.cornerStyle || this.cornerStyle) {
            case 'circle':
              e.beginPath(),
                e.arc(r + o / 2, n + o / 2, o / 2, 0, 2 * Math.PI, !1),
                e[i](),
                a && e.stroke();
              break;
            default:
              this.transparentCorners || e.clearRect(r, n, o, o),
                e[i + 'Rect'](r, n, o, o),
                a && e.strokeRect(r, n, o, o);
          }
        }
      },
      isControlVisible: function(t) {
        return this._getControlsVisibility()[t];
      },
      setControlVisible: function(t, e) {
        return (this._getControlsVisibility()[t] = e), this;
      },
      setControlsVisibility: function(t) {
        for (var e in (t || (t = {}), t)) this.setControlVisible(e, t[e]);
        return this;
      },
      _getControlsVisibility: function() {
        return (
          this._controlsVisibility ||
            (this._controlsVisibility = {
              tl: !0,
              tr: !0,
              br: !0,
              bl: !0,
              ml: !0,
              mt: !0,
              mr: !0,
              mb: !0,
              mtr: !0,
            }),
          this._controlsVisibility
        );
      },
      onDeselect: function() {},
      onSelect: function() {},
    });
  })(),
  fabric.util.object.extend(fabric.StaticCanvas.prototype, {
    FX_DURATION: 500,
    fxCenterObjectH: function(e, t) {
      var i = function() {},
        r = (t = t || {}).onComplete || i,
        n = t.onChange || i,
        s = this;
      return (
        fabric.util.animate({
          startValue: e.left,
          endValue: this.getCenter().left,
          duration: this.FX_DURATION,
          onChange: function(t) {
            e.set('left', t), s.requestRenderAll(), n();
          },
          onComplete: function() {
            e.setCoords(), r();
          },
        }),
        this
      );
    },
    fxCenterObjectV: function(e, t) {
      var i = function() {},
        r = (t = t || {}).onComplete || i,
        n = t.onChange || i,
        s = this;
      return (
        fabric.util.animate({
          startValue: e.top,
          endValue: this.getCenter().top,
          duration: this.FX_DURATION,
          onChange: function(t) {
            e.set('top', t), s.requestRenderAll(), n();
          },
          onComplete: function() {
            e.setCoords(), r();
          },
        }),
        this
      );
    },
    fxRemove: function(e, t) {
      var i = function() {},
        r = (t = t || {}).onComplete || i,
        n = t.onChange || i,
        s = this;
      return (
        fabric.util.animate({
          startValue: e.opacity,
          endValue: 0,
          duration: this.FX_DURATION,
          onChange: function(t) {
            e.set('opacity', t), s.requestRenderAll(), n();
          },
          onComplete: function() {
            s.remove(e), r();
          },
        }),
        this
      );
    },
  }),
  fabric.util.object.extend(fabric.Object.prototype, {
    animate: function() {
      if (arguments[0] && 'object' == typeof arguments[0]) {
        var t,
          e,
          i = [];
        for (t in arguments[0]) i.push(t);
        for (var r = 0, n = i.length; r < n; r++)
          (t = i[r]),
            (e = r !== n - 1),
            this._animate(t, arguments[0][t], arguments[1], e);
      } else this._animate.apply(this, arguments);
      return this;
    },
    _animate: function(r, t, n, s) {
      var o,
        a = this;
      (t = t.toString()),
        (n = n ? fabric.util.object.clone(n) : {}),
        ~r.indexOf('.') && (o = r.split('.'));
      var e = o ? this.get(o[0])[o[1]] : this.get(r);
      'from' in n || (n.from = e),
        (t = ~t.indexOf('=')
          ? e + parseFloat(t.replace('=', ''))
          : parseFloat(t)),
        fabric.util.animate({
          startValue: n.from,
          endValue: t,
          byValue: n.by,
          easing: n.easing,
          duration: n.duration,
          abort:
            n.abort &&
            function() {
              return n.abort.call(a);
            },
          onChange: function(t, e, i) {
            o ? (a[o[0]][o[1]] = t) : a.set(r, t),
              s || (n.onChange && n.onChange(t, e, i));
          },
          onComplete: function(t, e, i) {
            s || (a.setCoords(), n.onComplete && n.onComplete(t, e, i));
          },
        });
    },
  }),
  (function(t) {
    'use strict';
    var s = t.fabric || (t.fabric = {}),
      o = s.util.object.extend,
      r = s.util.object.clone,
      i = { x1: 1, x2: 1, y1: 1, y2: 1 },
      n = s.StaticCanvas.supports('setLineDash');
    function e(t, e) {
      var i = t.origin,
        r = t.axis1,
        n = t.axis2,
        s = t.dimension,
        o = e.nearest,
        a = e.center,
        h = e.farthest;
      return function() {
        switch (this.get(i)) {
          case o:
            return Math.min(this.get(r), this.get(n));
          case a:
            return Math.min(this.get(r), this.get(n)) + 0.5 * this.get(s);
          case h:
            return Math.max(this.get(r), this.get(n));
        }
      };
    }
    s.Line
      ? s.warn('fabric.Line is already defined')
      : ((s.Line = s.util.createClass(s.Object, {
          type: 'line',
          x1: 0,
          y1: 0,
          x2: 0,
          y2: 0,
          cacheProperties: s.Object.prototype.cacheProperties.concat(
            'x1',
            'x2',
            'y1',
            'y2'
          ),
          initialize: function(t, e) {
            t || (t = [0, 0, 0, 0]),
              this.callSuper('initialize', e),
              this.set('x1', t[0]),
              this.set('y1', t[1]),
              this.set('x2', t[2]),
              this.set('y2', t[3]),
              this._setWidthHeight(e);
          },
          _setWidthHeight: function(t) {
            t || (t = {}),
              (this.width = Math.abs(this.x2 - this.x1)),
              (this.height = Math.abs(this.y2 - this.y1)),
              (this.left = 'left' in t ? t.left : this._getLeftToOriginX()),
              (this.top = 'top' in t ? t.top : this._getTopToOriginY());
          },
          _set: function(t, e) {
            return (
              this.callSuper('_set', t, e),
              void 0 !== i[t] && this._setWidthHeight(),
              this
            );
          },
          _getLeftToOriginX: e(
            { origin: 'originX', axis1: 'x1', axis2: 'x2', dimension: 'width' },
            { nearest: 'left', center: 'center', farthest: 'right' }
          ),
          _getTopToOriginY: e(
            {
              origin: 'originY',
              axis1: 'y1',
              axis2: 'y2',
              dimension: 'height',
            },
            { nearest: 'top', center: 'center', farthest: 'bottom' }
          ),
          _render: function(t) {
            if (
              (t.beginPath(),
              !this.strokeDashArray || (this.strokeDashArray && n))
            ) {
              var e = this.calcLinePoints();
              t.moveTo(e.x1, e.y1), t.lineTo(e.x2, e.y2);
            }
            t.lineWidth = this.strokeWidth;
            var i = t.strokeStyle;
            (t.strokeStyle = this.stroke || t.fillStyle),
              this.stroke && this._renderStroke(t),
              (t.strokeStyle = i);
          },
          _renderDashedStroke: function(t) {
            var e = this.calcLinePoints();
            t.beginPath(),
              s.util.drawDashedLine(
                t,
                e.x1,
                e.y1,
                e.x2,
                e.y2,
                this.strokeDashArray
              ),
              t.closePath();
          },
          _findCenterFromElement: function() {
            return { x: (this.x1 + this.x2) / 2, y: (this.y1 + this.y2) / 2 };
          },
          toObject: function(t) {
            return o(this.callSuper('toObject', t), this.calcLinePoints());
          },
          _getNonTransformedDimensions: function() {
            var t = this.callSuper('_getNonTransformedDimensions');
            return (
              'butt' === this.strokeLineCap &&
                (0 === this.width && (t.y -= this.strokeWidth),
                0 === this.height && (t.x -= this.strokeWidth)),
              t
            );
          },
          calcLinePoints: function() {
            var t = this.x1 <= this.x2 ? -1 : 1,
              e = this.y1 <= this.y2 ? -1 : 1,
              i = t * this.width * 0.5,
              r = e * this.height * 0.5;
            return {
              x1: i,
              x2: t * this.width * -0.5,
              y1: r,
              y2: e * this.height * -0.5,
            };
          },
          _toSVG: function() {
            var t = this.calcLinePoints();
            return [
              '<line ',
              'COMMON_PARTS',
              'x1="',
              t.x1,
              '" y1="',
              t.y1,
              '" x2="',
              t.x2,
              '" y2="',
              t.y2,
              '" />\n',
            ];
          },
        })),
        (s.Line.ATTRIBUTE_NAMES = s.SHARED_ATTRIBUTES.concat(
          'x1 y1 x2 y2'.split(' ')
        )),
        (s.Line.fromElement = function(t, e, i) {
          i = i || {};
          var r = s.parseAttributes(t, s.Line.ATTRIBUTE_NAMES),
            n = [r.x1 || 0, r.y1 || 0, r.x2 || 0, r.y2 || 0];
          e(new s.Line(n, o(r, i)));
        }),
        (s.Line.fromObject = function(t, e) {
          var i = r(t, !0);
          (i.points = [t.x1, t.y1, t.x2, t.y2]),
            s.Object._fromObject(
              'Line',
              i,
              function(t) {
                delete t.points, e && e(t);
              },
              'points'
            );
        }));
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var a = t.fabric || (t.fabric = {}),
      h = Math.PI;
    a.Circle
      ? a.warn('fabric.Circle is already defined.')
      : ((a.Circle = a.util.createClass(a.Object, {
          type: 'circle',
          radius: 0,
          startAngle: 0,
          endAngle: 2 * h,
          cacheProperties: a.Object.prototype.cacheProperties.concat(
            'radius',
            'startAngle',
            'endAngle'
          ),
          _set: function(t, e) {
            return (
              this.callSuper('_set', t, e),
              'radius' === t && this.setRadius(e),
              this
            );
          },
          toObject: function(t) {
            return this.callSuper(
              'toObject',
              ['radius', 'startAngle', 'endAngle'].concat(t)
            );
          },
          _toSVG: function() {
            var t,
              e = (this.endAngle - this.startAngle) % (2 * h);
            if (0 === e)
              t = [
                '<circle ',
                'COMMON_PARTS',
                'cx="0" cy="0" ',
                'r="',
                this.radius,
                '" />\n',
              ];
            else {
              var i = a.util.cos(this.startAngle) * this.radius,
                r = a.util.sin(this.startAngle) * this.radius,
                n = a.util.cos(this.endAngle) * this.radius,
                s = a.util.sin(this.endAngle) * this.radius,
                o = h < e ? '1' : '0';
              t = [
                '<path d="M ' + i + ' ' + r,
                ' A ' + this.radius + ' ' + this.radius,
                ' 0 ',
                +o + ' 1',
                ' ' + n + ' ' + s,
                '"',
                'COMMON_PARTS',
                ' />\n',
              ];
            }
            return t;
          },
          _render: function(t) {
            t.beginPath(),
              t.arc(0, 0, this.radius, this.startAngle, this.endAngle, !1),
              this._renderPaintInOrder(t);
          },
          getRadiusX: function() {
            return this.get('radius') * this.get('scaleX');
          },
          getRadiusY: function() {
            return this.get('radius') * this.get('scaleY');
          },
          setRadius: function(t) {
            return (
              (this.radius = t), this.set('width', 2 * t).set('height', 2 * t)
            );
          },
        })),
        (a.Circle.ATTRIBUTE_NAMES = a.SHARED_ATTRIBUTES.concat(
          'cx cy r'.split(' ')
        )),
        (a.Circle.fromElement = function(t, e) {
          var i,
            r = a.parseAttributes(t, a.Circle.ATTRIBUTE_NAMES);
          if (!('radius' in (i = r) && 0 <= i.radius))
            throw new Error(
              'value of `r` attribute is required and can not be negative'
            );
          (r.left = (r.left || 0) - r.radius),
            (r.top = (r.top || 0) - r.radius),
            e(new a.Circle(r));
        }),
        (a.Circle.fromObject = function(t, e) {
          return a.Object._fromObject('Circle', t, e);
        }));
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var r = t.fabric || (t.fabric = {});
    r.Triangle
      ? r.warn('fabric.Triangle is already defined')
      : ((r.Triangle = r.util.createClass(r.Object, {
          type: 'triangle',
          width: 100,
          height: 100,
          _render: function(t) {
            var e = this.width / 2,
              i = this.height / 2;
            t.beginPath(),
              t.moveTo(-e, i),
              t.lineTo(0, -i),
              t.lineTo(e, i),
              t.closePath(),
              this._renderPaintInOrder(t);
          },
          _renderDashedStroke: function(t) {
            var e = this.width / 2,
              i = this.height / 2;
            t.beginPath(),
              r.util.drawDashedLine(t, -e, i, 0, -i, this.strokeDashArray),
              r.util.drawDashedLine(t, 0, -i, e, i, this.strokeDashArray),
              r.util.drawDashedLine(t, e, i, -e, i, this.strokeDashArray),
              t.closePath();
          },
          _toSVG: function() {
            var t = this.width / 2,
              e = this.height / 2;
            return [
              '<polygon ',
              'COMMON_PARTS',
              'points="',
              [-t + ' ' + e, '0 ' + -e, t + ' ' + e].join(','),
              '" />',
            ];
          },
        })),
        (r.Triangle.fromObject = function(t, e) {
          return r.Object._fromObject('Triangle', t, e);
        }));
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var r = t.fabric || (t.fabric = {}),
      e = 2 * Math.PI;
    r.Ellipse
      ? r.warn('fabric.Ellipse is already defined.')
      : ((r.Ellipse = r.util.createClass(r.Object, {
          type: 'ellipse',
          rx: 0,
          ry: 0,
          cacheProperties: r.Object.prototype.cacheProperties.concat(
            'rx',
            'ry'
          ),
          initialize: function(t) {
            this.callSuper('initialize', t),
              this.set('rx', (t && t.rx) || 0),
              this.set('ry', (t && t.ry) || 0);
          },
          _set: function(t, e) {
            switch ((this.callSuper('_set', t, e), t)) {
              case 'rx':
                (this.rx = e), this.set('width', 2 * e);
                break;
              case 'ry':
                (this.ry = e), this.set('height', 2 * e);
            }
            return this;
          },
          getRx: function() {
            return this.get('rx') * this.get('scaleX');
          },
          getRy: function() {
            return this.get('ry') * this.get('scaleY');
          },
          toObject: function(t) {
            return this.callSuper('toObject', ['rx', 'ry'].concat(t));
          },
          _toSVG: function() {
            return [
              '<ellipse ',
              'COMMON_PARTS',
              'cx="0" cy="0" ',
              'rx="',
              this.rx,
              '" ry="',
              this.ry,
              '" />\n',
            ];
          },
          _render: function(t) {
            t.beginPath(),
              t.save(),
              t.transform(1, 0, 0, this.ry / this.rx, 0, 0),
              t.arc(0, 0, this.rx, 0, e, !1),
              t.restore(),
              this._renderPaintInOrder(t);
          },
        })),
        (r.Ellipse.ATTRIBUTE_NAMES = r.SHARED_ATTRIBUTES.concat(
          'cx cy rx ry'.split(' ')
        )),
        (r.Ellipse.fromElement = function(t, e) {
          var i = r.parseAttributes(t, r.Ellipse.ATTRIBUTE_NAMES);
          (i.left = (i.left || 0) - i.rx),
            (i.top = (i.top || 0) - i.ry),
            e(new r.Ellipse(i));
        }),
        (r.Ellipse.fromObject = function(t, e) {
          return r.Object._fromObject('Ellipse', t, e);
        }));
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var s = t.fabric || (t.fabric = {}),
      o = s.util.object.extend;
    s.Rect
      ? s.warn('fabric.Rect is already defined')
      : ((s.Rect = s.util.createClass(s.Object, {
          stateProperties: s.Object.prototype.stateProperties.concat(
            'rx',
            'ry'
          ),
          type: 'rect',
          rx: 0,
          ry: 0,
          cacheProperties: s.Object.prototype.cacheProperties.concat(
            'rx',
            'ry'
          ),
          initialize: function(t) {
            this.callSuper('initialize', t), this._initRxRy();
          },
          _initRxRy: function() {
            this.rx && !this.ry
              ? (this.ry = this.rx)
              : this.ry && !this.rx && (this.rx = this.ry);
          },
          _render: function(t) {
            var e = this.rx ? Math.min(this.rx, this.width / 2) : 0,
              i = this.ry ? Math.min(this.ry, this.height / 2) : 0,
              r = this.width,
              n = this.height,
              s = -this.width / 2,
              o = -this.height / 2,
              a = 0 !== e || 0 !== i,
              h = 0.4477152502;
            t.beginPath(),
              t.moveTo(s + e, o),
              t.lineTo(s + r - e, o),
              a &&
                t.bezierCurveTo(
                  s + r - h * e,
                  o,
                  s + r,
                  o + h * i,
                  s + r,
                  o + i
                ),
              t.lineTo(s + r, o + n - i),
              a &&
                t.bezierCurveTo(
                  s + r,
                  o + n - h * i,
                  s + r - h * e,
                  o + n,
                  s + r - e,
                  o + n
                ),
              t.lineTo(s + e, o + n),
              a &&
                t.bezierCurveTo(
                  s + h * e,
                  o + n,
                  s,
                  o + n - h * i,
                  s,
                  o + n - i
                ),
              t.lineTo(s, o + i),
              a && t.bezierCurveTo(s, o + h * i, s + h * e, o, s + e, o),
              t.closePath(),
              this._renderPaintInOrder(t);
          },
          _renderDashedStroke: function(t) {
            var e = -this.width / 2,
              i = -this.height / 2,
              r = this.width,
              n = this.height;
            t.beginPath(),
              s.util.drawDashedLine(t, e, i, e + r, i, this.strokeDashArray),
              s.util.drawDashedLine(
                t,
                e + r,
                i,
                e + r,
                i + n,
                this.strokeDashArray
              ),
              s.util.drawDashedLine(
                t,
                e + r,
                i + n,
                e,
                i + n,
                this.strokeDashArray
              ),
              s.util.drawDashedLine(t, e, i + n, e, i, this.strokeDashArray),
              t.closePath();
          },
          toObject: function(t) {
            return this.callSuper('toObject', ['rx', 'ry'].concat(t));
          },
          _toSVG: function() {
            return [
              '<rect ',
              'COMMON_PARTS',
              'x="',
              -this.width / 2,
              '" y="',
              -this.height / 2,
              '" rx="',
              this.rx,
              '" ry="',
              this.ry,
              '" width="',
              this.width,
              '" height="',
              this.height,
              '" />\n',
            ];
          },
        })),
        (s.Rect.ATTRIBUTE_NAMES = s.SHARED_ATTRIBUTES.concat(
          'x y rx ry width height'.split(' ')
        )),
        (s.Rect.fromElement = function(t, e, i) {
          if (!t) return e(null);
          i = i || {};
          var r = s.parseAttributes(t, s.Rect.ATTRIBUTE_NAMES);
          (r.left = r.left || 0), (r.top = r.top || 0);
          var n = new s.Rect(o(i ? s.util.object.clone(i) : {}, r));
          (n.visible = n.visible && 0 < n.width && 0 < n.height), e(n);
        }),
        (s.Rect.fromObject = function(t, e) {
          return s.Object._fromObject('Rect', t, e);
        }));
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var o = t.fabric || (t.fabric = {}),
      e = o.util.object.extend,
      r = o.util.array.min,
      n = o.util.array.max,
      a = o.util.toFixed;
    o.Polyline
      ? o.warn('fabric.Polyline is already defined')
      : ((o.Polyline = o.util.createClass(o.Object, {
          type: 'polyline',
          points: null,
          cacheProperties: o.Object.prototype.cacheProperties.concat('points'),
          initialize: function(t, e) {
            (e = e || {}),
              (this.points = t || []),
              this.callSuper('initialize', e);
            var i = this._calcDimensions();
            void 0 === e.left && (this.left = i.left),
              void 0 === e.top && (this.top = i.top),
              (this.width = i.width),
              (this.height = i.height),
              (this.pathOffset = {
                x: i.left + this.width / 2,
                y: i.top + this.height / 2,
              });
          },
          _calcDimensions: function() {
            var t = this.points,
              e = r(t, 'x') || 0,
              i = r(t, 'y') || 0;
            return {
              left: e,
              top: i,
              width: (n(t, 'x') || 0) - e,
              height: (n(t, 'y') || 0) - i,
            };
          },
          toObject: function(t) {
            return e(this.callSuper('toObject', t), {
              points: this.points.concat(),
            });
          },
          _toSVG: function() {
            for (
              var t = [],
                e = this.pathOffset.x,
                i = this.pathOffset.y,
                r = o.Object.NUM_FRACTION_DIGITS,
                n = 0,
                s = this.points.length;
              n < s;
              n++
            )
              t.push(
                a(this.points[n].x - e, r),
                ',',
                a(this.points[n].y - i, r),
                ' '
              );
            return [
              '<' + this.type + ' ',
              'COMMON_PARTS',
              'points="',
              t.join(''),
              '" />\n',
            ];
          },
          commonRender: function(t) {
            var e,
              i = this.points.length,
              r = this.pathOffset.x,
              n = this.pathOffset.y;
            if (!i || isNaN(this.points[i - 1].y)) return !1;
            t.beginPath(), t.moveTo(this.points[0].x - r, this.points[0].y - n);
            for (var s = 0; s < i; s++)
              (e = this.points[s]), t.lineTo(e.x - r, e.y - n);
            return !0;
          },
          _render: function(t) {
            this.commonRender(t) && this._renderPaintInOrder(t);
          },
          _renderDashedStroke: function(t) {
            var e, i;
            t.beginPath();
            for (var r = 0, n = this.points.length; r < n; r++)
              (e = this.points[r]),
                (i = this.points[r + 1] || e),
                o.util.drawDashedLine(
                  t,
                  e.x,
                  e.y,
                  i.x,
                  i.y,
                  this.strokeDashArray
                );
          },
          complexity: function() {
            return this.get('points').length;
          },
        })),
        (o.Polyline.ATTRIBUTE_NAMES = o.SHARED_ATTRIBUTES.concat()),
        (o.Polyline.fromElement = function(t, e, i) {
          if (!t) return e(null);
          i || (i = {});
          var r = o.parsePointsAttribute(t.getAttribute('points')),
            n = o.parseAttributes(t, o.Polyline.ATTRIBUTE_NAMES);
          e(new o.Polyline(r, o.util.object.extend(n, i)));
        }),
        (o.Polyline.fromObject = function(t, e) {
          return o.Object._fromObject('Polyline', t, e, 'points');
        }));
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var s = t.fabric || (t.fabric = {}),
      o = s.util.object.extend;
    s.Polygon
      ? s.warn('fabric.Polygon is already defined')
      : ((s.Polygon = s.util.createClass(s.Polyline, {
          type: 'polygon',
          _render: function(t) {
            this.commonRender(t) &&
              (t.closePath(), this._renderPaintInOrder(t));
          },
          _renderDashedStroke: function(t) {
            this.callSuper('_renderDashedStroke', t), t.closePath();
          },
        })),
        (s.Polygon.ATTRIBUTE_NAMES = s.SHARED_ATTRIBUTES.concat()),
        (s.Polygon.fromElement = function(t, e, i) {
          if (!t) return e(null);
          i || (i = {});
          var r = s.parsePointsAttribute(t.getAttribute('points')),
            n = s.parseAttributes(t, s.Polygon.ATTRIBUTE_NAMES);
          e(new s.Polygon(r, o(n, i)));
        }),
        (s.Polygon.fromObject = function(t, e) {
          return s.Object._fromObject('Polygon', t, e, 'points');
        }));
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var m = t.fabric || (t.fabric = {}),
      b = m.util.array.min,
      _ = m.util.array.max,
      n = m.util.object.extend,
      r = Object.prototype.toString,
      p = m.util.drawArc,
      e = m.util.toFixed,
      y = { m: 2, l: 2, h: 1, v: 1, c: 6, s: 4, q: 4, t: 2, a: 7 },
      x = { m: 'l', M: 'L' };
    m.Path
      ? m.warn('fabric.Path is already defined')
      : ((m.Path = m.util.createClass(m.Object, {
          type: 'path',
          path: null,
          cacheProperties: m.Object.prototype.cacheProperties.concat(
            'path',
            'fillRule'
          ),
          stateProperties: m.Object.prototype.stateProperties.concat('path'),
          initialize: function(t, e) {
            (e = e || {}), this.callSuper('initialize', e), t || (t = []);
            var i = '[object Array]' === r.call(t);
            (this.path = i
              ? t
              : t.match && t.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi)),
              this.path &&
                (i || (this.path = this._parsePath()),
                this._setPositionDimensions(e));
          },
          _setPositionDimensions: function(t) {
            var e = this._parseDimensions();
            (this.width = e.width),
              (this.height = e.height),
              void 0 === t.left && (this.left = e.left),
              void 0 === t.top && (this.top = e.top),
              (this.pathOffset = this.pathOffset || {
                x: e.left + this.width / 2,
                y: e.top + this.height / 2,
              });
          },
          _renderPathCommands: function(t) {
            var e,
              i,
              r,
              n = null,
              s = 0,
              o = 0,
              a = 0,
              h = 0,
              c = 0,
              l = 0,
              u = -this.pathOffset.x,
              f = -this.pathOffset.y;
            t.beginPath();
            for (var d = 0, g = this.path.length; d < g; ++d) {
              switch ((e = this.path[d])[0]) {
                case 'l':
                  (a += e[1]), (h += e[2]), t.lineTo(a + u, h + f);
                  break;
                case 'L':
                  (a = e[1]), (h = e[2]), t.lineTo(a + u, h + f);
                  break;
                case 'h':
                  (a += e[1]), t.lineTo(a + u, h + f);
                  break;
                case 'H':
                  (a = e[1]), t.lineTo(a + u, h + f);
                  break;
                case 'v':
                  (h += e[1]), t.lineTo(a + u, h + f);
                  break;
                case 'V':
                  (h = e[1]), t.lineTo(a + u, h + f);
                  break;
                case 'm':
                  (s = a += e[1]), (o = h += e[2]), t.moveTo(a + u, h + f);
                  break;
                case 'M':
                  (s = a = e[1]), (o = h = e[2]), t.moveTo(a + u, h + f);
                  break;
                case 'c':
                  (i = a + e[5]),
                    (r = h + e[6]),
                    (c = a + e[3]),
                    (l = h + e[4]),
                    t.bezierCurveTo(
                      a + e[1] + u,
                      h + e[2] + f,
                      c + u,
                      l + f,
                      i + u,
                      r + f
                    ),
                    (a = i),
                    (h = r);
                  break;
                case 'C':
                  (a = e[5]),
                    (h = e[6]),
                    (c = e[3]),
                    (l = e[4]),
                    t.bezierCurveTo(
                      e[1] + u,
                      e[2] + f,
                      c + u,
                      l + f,
                      a + u,
                      h + f
                    );
                  break;
                case 's':
                  (i = a + e[3]),
                    (r = h + e[4]),
                    null === n[0].match(/[CcSs]/)
                      ? ((c = a), (l = h))
                      : ((c = 2 * a - c), (l = 2 * h - l)),
                    t.bezierCurveTo(
                      c + u,
                      l + f,
                      a + e[1] + u,
                      h + e[2] + f,
                      i + u,
                      r + f
                    ),
                    (c = a + e[1]),
                    (l = h + e[2]),
                    (a = i),
                    (h = r);
                  break;
                case 'S':
                  (i = e[3]),
                    (r = e[4]),
                    null === n[0].match(/[CcSs]/)
                      ? ((c = a), (l = h))
                      : ((c = 2 * a - c), (l = 2 * h - l)),
                    t.bezierCurveTo(
                      c + u,
                      l + f,
                      e[1] + u,
                      e[2] + f,
                      i + u,
                      r + f
                    ),
                    (a = i),
                    (h = r),
                    (c = e[1]),
                    (l = e[2]);
                  break;
                case 'q':
                  (i = a + e[3]),
                    (r = h + e[4]),
                    (c = a + e[1]),
                    (l = h + e[2]),
                    t.quadraticCurveTo(c + u, l + f, i + u, r + f),
                    (a = i),
                    (h = r);
                  break;
                case 'Q':
                  (i = e[3]),
                    (r = e[4]),
                    t.quadraticCurveTo(e[1] + u, e[2] + f, i + u, r + f),
                    (a = i),
                    (h = r),
                    (c = e[1]),
                    (l = e[2]);
                  break;
                case 't':
                  (i = a + e[1]),
                    (r = h + e[2]),
                    null === n[0].match(/[QqTt]/)
                      ? ((c = a), (l = h))
                      : ((c = 2 * a - c), (l = 2 * h - l)),
                    t.quadraticCurveTo(c + u, l + f, i + u, r + f),
                    (a = i),
                    (h = r);
                  break;
                case 'T':
                  (i = e[1]),
                    (r = e[2]),
                    null === n[0].match(/[QqTt]/)
                      ? ((c = a), (l = h))
                      : ((c = 2 * a - c), (l = 2 * h - l)),
                    t.quadraticCurveTo(c + u, l + f, i + u, r + f),
                    (a = i),
                    (h = r);
                  break;
                case 'a':
                  p(t, a + u, h + f, [
                    e[1],
                    e[2],
                    e[3],
                    e[4],
                    e[5],
                    e[6] + a + u,
                    e[7] + h + f,
                  ]),
                    (a += e[6]),
                    (h += e[7]);
                  break;
                case 'A':
                  p(t, a + u, h + f, [
                    e[1],
                    e[2],
                    e[3],
                    e[4],
                    e[5],
                    e[6] + u,
                    e[7] + f,
                  ]),
                    (a = e[6]),
                    (h = e[7]);
                  break;
                case 'z':
                case 'Z':
                  (a = s), (h = o), t.closePath();
              }
              n = e;
            }
          },
          _render: function(t) {
            this._renderPathCommands(t), this._renderPaintInOrder(t);
          },
          toString: function() {
            return (
              '#<fabric.Path (' +
              this.complexity() +
              '): { "top": ' +
              this.top +
              ', "left": ' +
              this.left +
              ' }>'
            );
          },
          toObject: function(t) {
            return n(this.callSuper('toObject', t), {
              path: this.path.map(function(t) {
                return t.slice();
              }),
              top: this.top,
              left: this.left,
            });
          },
          toDatalessObject: function(t) {
            var e = this.toObject(['sourcePath'].concat(t));
            return e.sourcePath && delete e.path, e;
          },
          _toSVG: function() {
            return [
              '<path ',
              'COMMON_PARTS',
              'd="',
              this.path
                .map(function(t) {
                  return t.join(' ');
                })
                .join(' '),
              '" stroke-linecap="round" ',
              '/>\n',
            ];
          },
          _getOffsetTransform: function() {
            var t = m.Object.NUM_FRACTION_DIGITS;
            return (
              ' translate(' +
              e(-this.pathOffset.x, t) +
              ', ' +
              e(-this.pathOffset.y, t) +
              ')'
            );
          },
          toClipPathSVG: function(t) {
            var e = this._getOffsetTransform();
            return (
              '\t' +
              this._createBaseClipPathSVGMarkup(this._toSVG(), {
                reviver: t,
                additionalTransform: e,
              })
            );
          },
          toSVG: function(t) {
            var e = this._getOffsetTransform();
            return this._createBaseSVGMarkup(this._toSVG(), {
              reviver: t,
              additionalTransform: e,
            });
          },
          complexity: function() {
            return this.path.length;
          },
          _parsePath: function() {
            for (
              var t,
                e,
                i,
                r,
                n,
                s = [],
                o = [],
                a = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,
                h = 0,
                c = this.path.length;
              h < c;
              h++
            ) {
              for (
                r = (t = this.path[h]).slice(1).trim(), o.length = 0;
                (i = a.exec(r));

              )
                o.push(i[0]);
              n = [t.charAt(0)];
              for (var l = 0, u = o.length; l < u; l++)
                (e = parseFloat(o[l])), isNaN(e) || n.push(e);
              var f = n[0],
                d = y[f.toLowerCase()],
                g = x[f] || f;
              if (n.length - 1 > d)
                for (var p = 1, v = n.length; p < v; p += d)
                  s.push([f].concat(n.slice(p, p + d))), (f = g);
              else s.push(n);
            }
            return s;
          },
          _parseDimensions: function() {
            for (
              var t,
                e,
                i,
                r,
                n = [],
                s = [],
                o = null,
                a = 0,
                h = 0,
                c = 0,
                l = 0,
                u = 0,
                f = 0,
                d = 0,
                g = this.path.length;
              d < g;
              ++d
            ) {
              switch ((t = this.path[d])[0]) {
                case 'l':
                  (c += t[1]), (l += t[2]), (r = []);
                  break;
                case 'L':
                  (c = t[1]), (l = t[2]), (r = []);
                  break;
                case 'h':
                  (c += t[1]), (r = []);
                  break;
                case 'H':
                  (c = t[1]), (r = []);
                  break;
                case 'v':
                  (l += t[1]), (r = []);
                  break;
                case 'V':
                  (l = t[1]), (r = []);
                  break;
                case 'm':
                  (a = c += t[1]), (h = l += t[2]), (r = []);
                  break;
                case 'M':
                  (a = c = t[1]), (h = l = t[2]), (r = []);
                  break;
                case 'c':
                  (e = c + t[5]),
                    (i = l + t[6]),
                    (u = c + t[3]),
                    (f = l + t[4]),
                    (r = m.util.getBoundsOfCurve(
                      c,
                      l,
                      c + t[1],
                      l + t[2],
                      u,
                      f,
                      e,
                      i
                    )),
                    (c = e),
                    (l = i);
                  break;
                case 'C':
                  (u = t[3]),
                    (f = t[4]),
                    (r = m.util.getBoundsOfCurve(
                      c,
                      l,
                      t[1],
                      t[2],
                      u,
                      f,
                      t[5],
                      t[6]
                    )),
                    (c = t[5]),
                    (l = t[6]);
                  break;
                case 's':
                  (e = c + t[3]),
                    (i = l + t[4]),
                    null === o[0].match(/[CcSs]/)
                      ? ((u = c), (f = l))
                      : ((u = 2 * c - u), (f = 2 * l - f)),
                    (r = m.util.getBoundsOfCurve(
                      c,
                      l,
                      u,
                      f,
                      c + t[1],
                      l + t[2],
                      e,
                      i
                    )),
                    (u = c + t[1]),
                    (f = l + t[2]),
                    (c = e),
                    (l = i);
                  break;
                case 'S':
                  (e = t[3]),
                    (i = t[4]),
                    null === o[0].match(/[CcSs]/)
                      ? ((u = c), (f = l))
                      : ((u = 2 * c - u), (f = 2 * l - f)),
                    (r = m.util.getBoundsOfCurve(c, l, u, f, t[1], t[2], e, i)),
                    (c = e),
                    (l = i),
                    (u = t[1]),
                    (f = t[2]);
                  break;
                case 'q':
                  (e = c + t[3]),
                    (i = l + t[4]),
                    (u = c + t[1]),
                    (f = l + t[2]),
                    (r = m.util.getBoundsOfCurve(c, l, u, f, u, f, e, i)),
                    (c = e),
                    (l = i);
                  break;
                case 'Q':
                  (u = t[1]),
                    (f = t[2]),
                    (r = m.util.getBoundsOfCurve(c, l, u, f, u, f, t[3], t[4])),
                    (c = t[3]),
                    (l = t[4]);
                  break;
                case 't':
                  (e = c + t[1]),
                    (i = l + t[2]),
                    null === o[0].match(/[QqTt]/)
                      ? ((u = c), (f = l))
                      : ((u = 2 * c - u), (f = 2 * l - f)),
                    (r = m.util.getBoundsOfCurve(c, l, u, f, u, f, e, i)),
                    (c = e),
                    (l = i);
                  break;
                case 'T':
                  (e = t[1]),
                    (i = t[2]),
                    null === o[0].match(/[QqTt]/)
                      ? ((u = c), (f = l))
                      : ((u = 2 * c - u), (f = 2 * l - f)),
                    (r = m.util.getBoundsOfCurve(c, l, u, f, u, f, e, i)),
                    (c = e),
                    (l = i);
                  break;
                case 'a':
                  (r = m.util.getBoundsOfArc(
                    c,
                    l,
                    t[1],
                    t[2],
                    t[3],
                    t[4],
                    t[5],
                    t[6] + c,
                    t[7] + l
                  )),
                    (c += t[6]),
                    (l += t[7]);
                  break;
                case 'A':
                  (r = m.util.getBoundsOfArc(
                    c,
                    l,
                    t[1],
                    t[2],
                    t[3],
                    t[4],
                    t[5],
                    t[6],
                    t[7]
                  )),
                    (c = t[6]),
                    (l = t[7]);
                  break;
                case 'z':
                case 'Z':
                  (c = a), (l = h);
              }
              (o = t),
                r.forEach(function(t) {
                  n.push(t.x), s.push(t.y);
                }),
                n.push(c),
                s.push(l);
            }
            var p = b(n) || 0,
              v = b(s) || 0;
            return {
              left: p,
              top: v,
              width: (_(n) || 0) - p,
              height: (_(s) || 0) - v,
            };
          },
        })),
        (m.Path.fromObject = function(i, r) {
          if ('string' == typeof i.sourcePath) {
            var t = i.sourcePath;
            m.loadSVGFromURL(t, function(t) {
              var e = t[0];
              e.setOptions(i), r && r(e);
            });
          } else m.Object._fromObject('Path', i, r, 'path');
        }),
        (m.Path.ATTRIBUTE_NAMES = m.SHARED_ATTRIBUTES.concat(['d'])),
        (m.Path.fromElement = function(t, e, i) {
          var r = m.parseAttributes(t, m.Path.ATTRIBUTE_NAMES);
          e(new m.Path(r.d, n(r, i)));
        }));
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var c = t.fabric || (t.fabric = {}),
      l = c.util.array.min,
      u = c.util.array.max;
    c.Group ||
      ((c.Group = c.util.createClass(c.Object, c.Collection, {
        type: 'group',
        strokeWidth: 0,
        subTargetCheck: !1,
        cacheProperties: [],
        useSetOnGroup: !1,
        initialize: function(t, e, i) {
          (e = e || {}),
            (this._objects = []),
            i && this.callSuper('initialize', e),
            (this._objects = t || []);
          for (var r = this._objects.length; r--; )
            this._objects[r].group = this;
          if (i) this._updateObjectsACoords();
          else {
            var n = e && e.centerPoint;
            void 0 !== e.originX && (this.originX = e.originX),
              void 0 !== e.originY && (this.originY = e.originY),
              n || this._calcBounds(),
              this._updateObjectsCoords(n),
              delete e.centerPoint,
              this.callSuper('initialize', e);
          }
          this.setCoords();
        },
        _updateObjectsACoords: function() {
          for (var t = this._objects.length; t--; )
            this._objects[t].setCoords(!0, !0);
        },
        _updateObjectsCoords: function(t) {
          t = t || this.getCenterPoint();
          for (var e = this._objects.length; e--; )
            this._updateObjectCoords(this._objects[e], t);
        },
        _updateObjectCoords: function(t, e) {
          var i = t.left,
            r = t.top;
          t.set({ left: i - e.x, top: r - e.y }),
            (t.group = this),
            t.setCoords(!0, !0);
        },
        toString: function() {
          return '#<fabric.Group: (' + this.complexity() + ')>';
        },
        addWithUpdate: function(t) {
          return (
            this._restoreObjectsState(),
            c.util.resetObjectTransform(this),
            t &&
              (this._objects.push(t),
              (t.group = this),
              t._set('canvas', this.canvas)),
            this._calcBounds(),
            this._updateObjectsCoords(),
            this.setCoords(),
            (this.dirty = !0),
            this
          );
        },
        removeWithUpdate: function(t) {
          return (
            this._restoreObjectsState(),
            c.util.resetObjectTransform(this),
            this.remove(t),
            this._calcBounds(),
            this._updateObjectsCoords(),
            this.setCoords(),
            (this.dirty = !0),
            this
          );
        },
        _onObjectAdded: function(t) {
          (this.dirty = !0), (t.group = this), t._set('canvas', this.canvas);
        },
        _onObjectRemoved: function(t) {
          (this.dirty = !0), delete t.group;
        },
        _set: function(t, e) {
          var i = this._objects.length;
          if (this.useSetOnGroup)
            for (; i--; ) this._objects[i].setOnGroup(t, e);
          if ('canvas' === t) for (; i--; ) this._objects[i]._set(t, e);
          c.Object.prototype._set.call(this, t, e);
        },
        toObject: function(r) {
          var n = this.includeDefaultValues,
            t = this._objects.map(function(t) {
              var e = t.includeDefaultValues;
              t.includeDefaultValues = n;
              var i = t.toObject(r);
              return (t.includeDefaultValues = e), i;
            }),
            e = c.Object.prototype.toObject.call(this, r);
          return (e.objects = t), e;
        },
        toDatalessObject: function(r) {
          var t,
            e = this.sourcePath;
          if (e) t = e;
          else {
            var n = this.includeDefaultValues;
            t = this._objects.map(function(t) {
              var e = t.includeDefaultValues;
              t.includeDefaultValues = n;
              var i = t.toDatalessObject(r);
              return (t.includeDefaultValues = e), i;
            });
          }
          var i = c.Object.prototype.toDatalessObject.call(this, r);
          return (i.objects = t), i;
        },
        render: function(t) {
          (this._transformDone = !0),
            this.callSuper('render', t),
            (this._transformDone = !1);
        },
        shouldCache: function() {
          var t =
            this.objectCaching &&
            (!this.group ||
              this.needsItsOwnCache() ||
              !this.group.isOnACache());
          if ((this.ownCaching = t))
            for (var e = 0, i = this._objects.length; e < i; e++)
              if (this._objects[e].willDrawShadow())
                return (this.ownCaching = !1);
          return t;
        },
        willDrawShadow: function() {
          if (this.shadow) return c.Object.prototype.willDrawShadow.call(this);
          for (var t = 0, e = this._objects.length; t < e; t++)
            if (this._objects[t].willDrawShadow()) return !0;
          return !1;
        },
        isOnACache: function() {
          return this.ownCaching || (this.group && this.group.isOnACache());
        },
        drawObject: function(t) {
          for (var e = 0, i = this._objects.length; e < i; e++)
            this._objects[e].render(t);
          this._drawClipPath(t);
        },
        isCacheDirty: function(t) {
          if (this.callSuper('isCacheDirty', t)) return !0;
          if (!this.statefullCache) return !1;
          for (var e = 0, i = this._objects.length; e < i; e++)
            if (this._objects[e].isCacheDirty(!0)) {
              if (this._cacheCanvas) {
                var r = this.cacheWidth / this.zoomX,
                  n = this.cacheHeight / this.zoomY;
                this._cacheContext.clearRect(-r / 2, -n / 2, r, n);
              }
              return !0;
            }
          return !1;
        },
        _restoreObjectsState: function() {
          return this._objects.forEach(this._restoreObjectState, this), this;
        },
        realizeTransform: function(t) {
          var e = t.calcTransformMatrix(),
            i = c.util.qrDecompose(e),
            r = new c.Point(i.translateX, i.translateY);
          return (
            (t.flipX = !1),
            (t.flipY = !1),
            t.set('scaleX', i.scaleX),
            t.set('scaleY', i.scaleY),
            (t.skewX = i.skewX),
            (t.skewY = i.skewY),
            (t.angle = i.angle),
            t.setPositionByOrigin(r, 'center', 'center'),
            t
          );
        },
        _restoreObjectState: function(t) {
          return this.realizeTransform(t), t.setCoords(), delete t.group, this;
        },
        destroy: function() {
          return (
            this._objects.forEach(function(t) {
              t.set('dirty', !0);
            }),
            this._restoreObjectsState()
          );
        },
        toActiveSelection: function() {
          if (this.canvas) {
            var t = this._objects,
              e = this.canvas;
            this._objects = [];
            var i = this.toObject();
            delete i.objects;
            var r = new c.ActiveSelection([]);
            return (
              r.set(i),
              (r.type = 'activeSelection'),
              e.remove(this),
              t.forEach(function(t) {
                (t.group = r), (t.dirty = !0), e.add(t);
              }),
              (r.canvas = e),
              (r._objects = t),
              (e._activeObject = r).setCoords(),
              r
            );
          }
        },
        ungroupOnCanvas: function() {
          return this._restoreObjectsState();
        },
        setObjectsCoords: function() {
          return (
            this.forEachObject(function(t) {
              t.setCoords(!0, !0);
            }),
            this
          );
        },
        _calcBounds: function(t) {
          for (
            var e,
              i,
              r,
              n = [],
              s = [],
              o = ['tr', 'br', 'bl', 'tl'],
              a = 0,
              h = this._objects.length,
              c = o.length;
            a < h;
            ++a
          )
            for ((e = this._objects[a]).setCoords(!0), r = 0; r < c; r++)
              (i = o[r]), n.push(e.oCoords[i].x), s.push(e.oCoords[i].y);
          this._getBounds(n, s, t);
        },
        _getBounds: function(t, e, i) {
          var r = new c.Point(l(t), l(e)),
            n = new c.Point(u(t), u(e)),
            s = r.y || 0,
            o = r.x || 0,
            a = n.x - r.x || 0,
            h = n.y - r.y || 0;
          (this.width = a),
            (this.height = h),
            i || this.setPositionByOrigin({ x: o, y: s }, 'left', 'top');
        },
        toSVG: function(t) {
          for (var e = [], i = 0, r = this._objects.length; i < r; i++)
            e.push('\t', this._objects[i].toSVG(t));
          return this._createBaseSVGMarkup(e, {
            reviver: t,
            noStyle: !0,
            withShadow: !0,
          });
        },
        toClipPathSVG: function(t) {
          for (var e = [], i = 0, r = this._objects.length; i < r; i++)
            e.push('\t', this._objects[i].toClipPathSVG(t));
          return this._createBaseClipPathSVGMarkup(e, { reviver: t });
        },
      })),
      (c.Group.fromObject = function(r, n) {
        c.util.enlivenObjects(r.objects, function(i) {
          c.util.enlivenObjects([r.clipPath], function(t) {
            var e = c.util.object.clone(r, !0);
            (e.clipPath = t[0]),
              delete e.objects,
              n && n(new c.Group(i, e, !0));
          });
        });
      }));
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var n = t.fabric || (t.fabric = {});
    n.ActiveSelection ||
      ((n.ActiveSelection = n.util.createClass(n.Group, {
        type: 'activeSelection',
        initialize: function(t, e) {
          (e = e || {}), (this._objects = t || []);
          for (var i = this._objects.length; i--; )
            this._objects[i].group = this;
          e.originX && (this.originX = e.originX),
            e.originY && (this.originY = e.originY),
            this._calcBounds(),
            this._updateObjectsCoords(),
            n.Object.prototype.initialize.call(this, e),
            this.setCoords();
        },
        toGroup: function() {
          var t = this._objects.concat();
          this._objects = [];
          var e = n.Object.prototype.toObject.call(this),
            i = new n.Group([]);
          if (
            (delete e.type,
            i.set(e),
            t.forEach(function(t) {
              t.canvas.remove(t), (t.group = i);
            }),
            (i._objects = t),
            !this.canvas)
          )
            return i;
          var r = this.canvas;
          return r.add(i), (r._activeObject = i).setCoords(), i;
        },
        onDeselect: function() {
          return this.destroy(), !1;
        },
        toString: function() {
          return '#<fabric.ActiveSelection: (' + this.complexity() + ')>';
        },
        shouldCache: function() {
          return !1;
        },
        isOnACache: function() {
          return !1;
        },
        _renderControls: function(t, e, i) {
          t.save(),
            (t.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1),
            this.callSuper('_renderControls', t, e),
            void 0 === (i = i || {}).hasControls && (i.hasControls = !1),
            void 0 === i.hasRotatingPoint && (i.hasRotatingPoint = !1),
            (i.forActiveSelection = !0);
          for (var r = 0, n = this._objects.length; r < n; r++)
            this._objects[r]._renderControls(t, i);
          t.restore();
        },
      })),
      (n.ActiveSelection.fromObject = function(e, i) {
        n.util.enlivenObjects(e.objects, function(t) {
          delete e.objects, i && i(new n.ActiveSelection(t, e, !0));
        });
      }));
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var n = fabric.util.object.extend;
    t.fabric || (t.fabric = {}),
      t.fabric.Image
        ? fabric.warn('fabric.Image is already defined.')
        : ((fabric.Image = fabric.util.createClass(fabric.Object, {
            type: 'image',
            crossOrigin: '',
            strokeWidth: 0,
            _lastScaleX: 1,
            _lastScaleY: 1,
            _filterScalingX: 1,
            _filterScalingY: 1,
            minimumScaleTrigger: 0.5,
            stateProperties: fabric.Object.prototype.stateProperties.concat(
              'cropX',
              'cropY'
            ),
            cacheKey: '',
            cropX: 0,
            cropY: 0,
            initialize: function(t, e) {
              e || (e = {}),
                (this.filters = []),
                (this.cacheKey = 'texture' + fabric.Object.__uid++),
                this.callSuper('initialize', e),
                this._initElement(t, e);
            },
            getElement: function() {
              return this._element || {};
            },
            setElement: function(t, e) {
              return (
                this.removeTexture(this.cacheKey),
                this.removeTexture(this.cacheKey + '_filtered'),
                (this._element = t),
                (this._originalElement = t),
                this._initConfig(e),
                0 !== this.filters.length && this.applyFilters(),
                this.resizeFilter && this.applyResizeFilters(),
                this
              );
            },
            removeTexture: function(t) {
              var e = fabric.filterBackend;
              e && e.evictCachesForKey && e.evictCachesForKey(t);
            },
            dispose: function() {
              this.removeTexture(this.cacheKey),
                this.removeTexture(this.cacheKey + '_filtered'),
                (this._cacheContext = void 0),
                [
                  '_originalElement',
                  '_element',
                  '_filteredEl',
                  '_cacheCanvas',
                ].forEach(
                  function(t) {
                    fabric.util.cleanUpJsdomNode(this[t]), (this[t] = void 0);
                  }.bind(this)
                );
            },
            setCrossOrigin: function(t) {
              return (
                (this.crossOrigin = t), (this._element.crossOrigin = t), this
              );
            },
            getOriginalSize: function() {
              var t = this.getElement();
              return {
                width: t.naturalWidth || t.width,
                height: t.naturalHeight || t.height,
              };
            },
            _stroke: function(t) {
              if (this.stroke && 0 !== this.strokeWidth) {
                var e = this.width / 2,
                  i = this.height / 2;
                t.beginPath(),
                  t.moveTo(-e, -i),
                  t.lineTo(e, -i),
                  t.lineTo(e, i),
                  t.lineTo(-e, i),
                  t.lineTo(-e, -i),
                  t.closePath();
              }
            },
            _renderDashedStroke: function(t) {
              var e = -this.width / 2,
                i = -this.height / 2,
                r = this.width,
                n = this.height;
              t.save(),
                this._setStrokeStyles(t, this),
                t.beginPath(),
                fabric.util.drawDashedLine(
                  t,
                  e,
                  i,
                  e + r,
                  i,
                  this.strokeDashArray
                ),
                fabric.util.drawDashedLine(
                  t,
                  e + r,
                  i,
                  e + r,
                  i + n,
                  this.strokeDashArray
                ),
                fabric.util.drawDashedLine(
                  t,
                  e + r,
                  i + n,
                  e,
                  i + n,
                  this.strokeDashArray
                ),
                fabric.util.drawDashedLine(
                  t,
                  e,
                  i + n,
                  e,
                  i,
                  this.strokeDashArray
                ),
                t.closePath(),
                t.restore();
            },
            toObject: function(t) {
              var e = [];
              this.filters.forEach(function(t) {
                t && e.push(t.toObject());
              });
              var i = n(
                this.callSuper(
                  'toObject',
                  ['crossOrigin', 'cropX', 'cropY'].concat(t)
                ),
                { src: this.getSrc(), filters: e }
              );
              return (
                this.resizeFilter &&
                  (i.resizeFilter = this.resizeFilter.toObject()),
                i
              );
            },
            hasCrop: function() {
              return (
                this.cropX ||
                this.cropY ||
                this.width < this._element.width ||
                this.height < this._element.height
              );
            },
            _toSVG: function() {
              var t,
                e = [],
                i = [],
                r = -this.width / 2,
                n = -this.height / 2,
                s = '';
              if (this.hasCrop()) {
                var o = fabric.Object.__uid++;
                e.push(
                  '<clipPath id="imageCrop_' + o + '">\n',
                  '\t<rect x="' +
                    r +
                    '" y="' +
                    n +
                    '" width="' +
                    this.width +
                    '" height="' +
                    this.height +
                    '" />\n',
                  '</clipPath>\n'
                ),
                  (s = ' clip-path="url(#imageCrop_' + o + ')" ');
              }
              if (
                (i.push(
                  '\t<image ',
                  'COMMON_PARTS',
                  'xlink:href="',
                  this.getSvgSrc(!0),
                  '" x="',
                  r - this.cropX,
                  '" y="',
                  n - this.cropY,
                  '" width="',
                  this._element.width || this._element.naturalWidth,
                  '" height="',
                  this._element.height || this._element.height,
                  '"',
                  s,
                  '></image>\n'
                ),
                this.stroke || this.strokeDashArray)
              ) {
                var a = this.fill;
                (this.fill = null),
                  (t = [
                    '\t<rect ',
                    'x="',
                    r,
                    '" y="',
                    n,
                    '" width="',
                    this.width,
                    '" height="',
                    this.height,
                    '" style="',
                    this.getSvgStyles(),
                    '"/>\n',
                  ]),
                  (this.fill = a);
              }
              return (e =
                'fill' !== this.paintFirst ? e.concat(t, i) : e.concat(i, t));
            },
            getSrc: function(t) {
              var e = t ? this._element : this._originalElement;
              return e ? (e.toDataURL ? e.toDataURL() : e.src) : this.src || '';
            },
            setSrc: function(t, e, i) {
              return (
                fabric.util.loadImage(
                  t,
                  function(t) {
                    this.setElement(t, i), this._setWidthHeight(), e(this);
                  },
                  this,
                  i && i.crossOrigin
                ),
                this
              );
            },
            toString: function() {
              return '#<fabric.Image: { src: "' + this.getSrc() + '" }>';
            },
            applyResizeFilters: function() {
              var t = this.resizeFilter,
                e = this.minimumScaleTrigger,
                i = this.getTotalObjectScaling(),
                r = i.scaleX,
                n = i.scaleY,
                s = this._filteredEl || this._originalElement;
              if ((this.group && this.set('dirty', !0), !t || (e < r && e < n)))
                return (
                  (this._element = s),
                  (this._filterScalingX = 1),
                  (this._filterScalingY = 1),
                  (this._lastScaleX = r),
                  void (this._lastScaleY = n)
                );
              fabric.filterBackend ||
                (fabric.filterBackend = fabric.initFilterBackend());
              var o = fabric.util.createCanvasElement(),
                a = this._filteredEl
                  ? this.cacheKey + '_filtered'
                  : this.cacheKey,
                h = s.width,
                c = s.height;
              (o.width = h),
                (o.height = c),
                (this._element = o),
                (this._lastScaleX = t.scaleX = r),
                (this._lastScaleY = t.scaleY = n),
                fabric.filterBackend.applyFilters(
                  [t],
                  s,
                  h,
                  c,
                  this._element,
                  a
                ),
                (this._filterScalingX = o.width / this._originalElement.width),
                (this._filterScalingY =
                  o.height / this._originalElement.height);
            },
            applyFilters: function(t) {
              if (
                ((t = (t = t || this.filters || []).filter(function(t) {
                  return t && !t.isNeutralState();
                })),
                this.set('dirty', !0),
                this.removeTexture(this.cacheKey + '_filtered'),
                0 === t.length)
              )
                return (
                  (this._element = this._originalElement),
                  (this._filteredEl = null),
                  (this._filterScalingX = 1),
                  (this._filterScalingY = 1),
                  this
                );
              var e = this._originalElement,
                i = e.naturalWidth || e.width,
                r = e.naturalHeight || e.height;
              if (this._element === this._originalElement) {
                var n = fabric.util.createCanvasElement();
                (n.width = i),
                  (n.height = r),
                  (this._element = n),
                  (this._filteredEl = n);
              } else
                (this._element = this._filteredEl),
                  this._filteredEl.getContext('2d').clearRect(0, 0, i, r),
                  (this._lastScaleX = 1),
                  (this._lastScaleY = 1);
              return (
                fabric.filterBackend ||
                  (fabric.filterBackend = fabric.initFilterBackend()),
                fabric.filterBackend.applyFilters(
                  t,
                  this._originalElement,
                  i,
                  r,
                  this._element,
                  this.cacheKey
                ),
                (this._originalElement.width === this._element.width &&
                  this._originalElement.height === this._element.height) ||
                  ((this._filterScalingX =
                    this._element.width / this._originalElement.width),
                  (this._filterScalingY =
                    this._element.height / this._originalElement.height)),
                this
              );
            },
            _render: function(t) {
              !0 !== this.isMoving &&
                this.resizeFilter &&
                this._needsResize() &&
                this.applyResizeFilters(),
                this._stroke(t),
                this._renderPaintInOrder(t);
            },
            shouldCache: function() {
              return (
                (this.ownCaching =
                  this.objectCaching && this.needsItsOwnCache()),
                this.ownCaching
              );
            },
            _renderFill: function(t) {
              var e = this.width,
                i = this.height,
                r = e * this._filterScalingX,
                n = i * this._filterScalingY,
                s = -e / 2,
                o = -i / 2,
                a = this._element;
              a &&
                t.drawImage(
                  a,
                  this.cropX * this._filterScalingX,
                  this.cropY * this._filterScalingY,
                  r,
                  n,
                  s,
                  o,
                  e,
                  i
                );
            },
            _needsResize: function() {
              var t = this.getTotalObjectScaling();
              return (
                t.scaleX !== this._lastScaleX || t.scaleY !== this._lastScaleY
              );
            },
            _resetWidthHeight: function() {
              this.set(this.getOriginalSize());
            },
            _initElement: function(t, e) {
              this.setElement(fabric.util.getById(t), e),
                fabric.util.addClass(
                  this.getElement(),
                  fabric.Image.CSS_CANVAS
                );
            },
            _initConfig: function(t) {
              t || (t = {}),
                this.setOptions(t),
                this._setWidthHeight(t),
                this._element &&
                  this.crossOrigin &&
                  (this._element.crossOrigin = this.crossOrigin);
            },
            _initFilters: function(t, e) {
              t && t.length
                ? fabric.util.enlivenObjects(
                    t,
                    function(t) {
                      e && e(t);
                    },
                    'fabric.Image.filters'
                  )
                : e && e();
            },
            _setWidthHeight: function(t) {
              t || (t = {});
              var e = this.getElement();
              (this.width = t.width || e.naturalWidth || e.width || 0),
                (this.height = t.height || e.naturalHeight || e.height || 0);
            },
            parsePreserveAspectRatioAttribute: function() {
              var t,
                e = fabric.util.parsePreserveAspectRatioAttribute(
                  this.preserveAspectRatio || ''
                ),
                i = this._element.width,
                r = this._element.height,
                n = 1,
                s = 1,
                o = 0,
                a = 0,
                h = 0,
                c = 0,
                l = this.width,
                u = this.height,
                f = { width: l, height: u };
              return (
                !e || ('none' === e.alignX && 'none' === e.alignY)
                  ? ((n = l / i), (s = u / r))
                  : ('meet' === e.meetOrSlice &&
                      ((t =
                        (l -
                          i *
                            (n = s = fabric.util.findScaleToFit(
                              this._element,
                              f
                            ))) /
                        2),
                      'Min' === e.alignX && (o = -t),
                      'Max' === e.alignX && (o = t),
                      (t = (u - r * s) / 2),
                      'Min' === e.alignY && (a = -t),
                      'Max' === e.alignY && (a = t)),
                    'slice' === e.meetOrSlice &&
                      ((t =
                        i -
                        l /
                          (n = s = fabric.util.findScaleToCover(
                            this._element,
                            f
                          ))),
                      'Mid' === e.alignX && (h = t / 2),
                      'Max' === e.alignX && (h = t),
                      (t = r - u / s),
                      'Mid' === e.alignY && (c = t / 2),
                      'Max' === e.alignY && (c = t),
                      (i = l / n),
                      (r = u / s))),
                {
                  width: i,
                  height: r,
                  scaleX: n,
                  scaleY: s,
                  offsetLeft: o,
                  offsetTop: a,
                  cropX: h,
                  cropY: c,
                }
              );
            },
          })),
          (fabric.Image.CSS_CANVAS = 'canvas-img'),
          (fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc),
          (fabric.Image.fromObject = function(t, r) {
            var n = fabric.util.object.clone(t);
            fabric.util.loadImage(
              n.src,
              function(i, t) {
                t
                  ? r && r(null, t)
                  : fabric.Image.prototype._initFilters.call(
                      n,
                      n.filters,
                      function(t) {
                        (n.filters = t || []),
                          fabric.Image.prototype._initFilters.call(
                            n,
                            [n.resizeFilter],
                            function(t) {
                              (n.resizeFilter = t[0]),
                                fabric.util.enlivenObjects(
                                  [n.clipPath],
                                  function(t) {
                                    n.clipPath = t[0];
                                    var e = new fabric.Image(i, n);
                                    r(e);
                                  }
                                );
                            }
                          );
                      }
                    );
              },
              null,
              n.crossOrigin
            );
          }),
          (fabric.Image.fromURL = function(t, e, i) {
            fabric.util.loadImage(
              t,
              function(t) {
                e && e(new fabric.Image(t, i));
              },
              null,
              i && i.crossOrigin
            );
          }),
          (fabric.Image.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(
            'x y width height preserveAspectRatio xlink:href crossOrigin'.split(
              ' '
            )
          )),
          (fabric.Image.fromElement = function(t, e, i) {
            var r = fabric.parseAttributes(t, fabric.Image.ATTRIBUTE_NAMES);
            fabric.Image.fromURL(
              r['xlink:href'],
              e,
              n(i ? fabric.util.object.clone(i) : {}, r)
            );
          }));
  })('undefined' != typeof exports ? exports : this),
  fabric.util.object.extend(fabric.Object.prototype, {
    _getAngleValueForStraighten: function() {
      var t = this.angle % 360;
      return 0 < t ? 90 * Math.round((t - 1) / 90) : 90 * Math.round(t / 90);
    },
    straighten: function() {
      return this.rotate(this._getAngleValueForStraighten()), this;
    },
    fxStraighten: function(t) {
      var e = function() {},
        i = (t = t || {}).onComplete || e,
        r = t.onChange || e,
        n = this;
      return (
        fabric.util.animate({
          startValue: this.get('angle'),
          endValue: this._getAngleValueForStraighten(),
          duration: this.FX_DURATION,
          onChange: function(t) {
            n.rotate(t), r();
          },
          onComplete: function() {
            n.setCoords(), i();
          },
        }),
        this
      );
    },
  }),
  fabric.util.object.extend(fabric.StaticCanvas.prototype, {
    straightenObject: function(t) {
      return t.straighten(), this.requestRenderAll(), this;
    },
    fxStraightenObject: function(t) {
      return t.fxStraighten({ onChange: this.requestRenderAllBound }), this;
    },
  }),
  (function() {
    'use strict';
    function t(t) {
      t && t.tileSize && (this.tileSize = t.tileSize),
        this.setupGLContext(this.tileSize, this.tileSize),
        this.captureGPUInfo();
    }
    (fabric.isWebglSupported = function(t) {
      if (fabric.isLikelyNode) return !1;
      t = t || fabric.WebglFilterBackend.prototype.tileSize;
      var e,
        i,
        r,
        n = document.createElement('canvas'),
        s = n.getContext('webgl') || n.getContext('experimental-webgl'),
        o = !1;
      if (s) {
        (fabric.maxTextureSize = s.getParameter(s.MAX_TEXTURE_SIZE)),
          (o = fabric.maxTextureSize >= t);
        for (var a = ['highp', 'mediump', 'lowp'], h = 0; h < 3; h++)
          if (
            (void 0,
            (i = 'precision ' + a[h] + ' float;\nvoid main(){}'),
            (r = (e = s).createShader(e.FRAGMENT_SHADER)),
            e.shaderSource(r, i),
            e.compileShader(r),
            e.getShaderParameter(r, e.COMPILE_STATUS))
          ) {
            fabric.webGlPrecision = a[h];
            break;
          }
      }
      return (this.isSupported = o);
    }),
      ((fabric.WebglFilterBackend = t).prototype = {
        tileSize: 2048,
        resources: {},
        setupGLContext: function(t, e) {
          this.dispose(),
            this.createWebGLCanvas(t, e),
            (this.aPosition = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1])),
            this.chooseFastestCopyGLTo2DMethod(t, e);
        },
        chooseFastestCopyGLTo2DMethod: function(t, e) {
          var i,
            r = void 0 !== window.performance;
          try {
            new ImageData(1, 1), (i = !0);
          } catch (t) {
            i = !1;
          }
          var n = 'undefined' != typeof ArrayBuffer,
            s = 'undefined' != typeof Uint8ClampedArray;
          if (r && i && n && s) {
            var o,
              a,
              h = fabric.util.createCanvasElement(),
              c = new ArrayBuffer(t * e * 4),
              l = {
                imageBuffer: c,
                destinationWidth: t,
                destinationHeight: e,
                targetCanvas: h,
              };
            (h.width = t),
              (h.height = e),
              (o = window.performance.now()),
              copyGLTo2DDrawImage.call(l, this.gl, l),
              (a = window.performance.now() - o),
              (o = window.performance.now()),
              copyGLTo2DPutImageData.call(l, this.gl, l),
              window.performance.now() - o < a
                ? ((this.imageBuffer = c),
                  (this.copyGLTo2D = copyGLTo2DPutImageData))
                : (this.copyGLTo2D = copyGLTo2DDrawImage);
          }
        },
        createWebGLCanvas: function(t, e) {
          var i = fabric.util.createCanvasElement();
          (i.width = t), (i.height = e);
          var r = {
              alpha: !0,
              premultipliedAlpha: !1,
              depth: !1,
              stencil: !1,
              antialias: !1,
            },
            n = i.getContext('webgl', r);
          n || (n = i.getContext('experimental-webgl', r)),
            n && (n.clearColor(0, 0, 0, 0), (this.canvas = i), (this.gl = n));
        },
        applyFilters: function(t, e, i, r, n, s) {
          var o,
            a = this.gl;
          s && (o = this.getCachedTexture(s, e));
          var h = {
              originalWidth: e.width || e.originalWidth,
              originalHeight: e.height || e.originalHeight,
              sourceWidth: i,
              sourceHeight: r,
              destinationWidth: i,
              destinationHeight: r,
              context: a,
              sourceTexture: this.createTexture(a, i, r, !o && e),
              targetTexture: this.createTexture(a, i, r),
              originalTexture: o || this.createTexture(a, i, r, !o && e),
              passes: t.length,
              webgl: !0,
              aPosition: this.aPosition,
              programCache: this.programCache,
              pass: 0,
              filterBackend: this,
              targetCanvas: n,
            },
            c = a.createFramebuffer();
          return (
            a.bindFramebuffer(a.FRAMEBUFFER, c),
            t.forEach(function(t) {
              t && t.applyTo(h);
            }),
            resizeCanvasIfNeeded(h),
            this.copyGLTo2D(a, h),
            a.bindTexture(a.TEXTURE_2D, null),
            a.deleteTexture(h.sourceTexture),
            a.deleteTexture(h.targetTexture),
            a.deleteFramebuffer(c),
            n.getContext('2d').setTransform(1, 0, 0, 1, 0, 0),
            h
          );
        },
        applyFiltersDebug: function(t, e, i, r, n, s) {
          var o = this.gl,
            a = this.applyFilters(t, e, i, r, n, s),
            h = o.getError();
          if (h !== o.NO_ERROR) {
            var c = this.glErrorToString(o, h),
              l = new Error('WebGL Error ' + c);
            throw ((l.glErrorCode = h), l);
          }
          return a;
        },
        glErrorToString: function(t, e) {
          if (!t) return 'Context undefined for error code: ' + e;
          if ('number' != typeof e) return 'Error code is not a number';
          switch (e) {
            case t.NO_ERROR:
              return 'NO_ERROR';
            case t.INVALID_ENUM:
              return 'INVALID_ENUM';
            case t.INVALID_VALUE:
              return 'INVALID_VALUE';
            case t.INVALID_OPERATION:
              return 'INVALID_OPERATION';
            case t.INVALID_FRAMEBUFFER_OPERATION:
              return 'INVALID_FRAMEBUFFER_OPERATION';
            case t.OUT_OF_MEMORY:
              return 'OUT_OF_MEMORY';
            case t.CONTEXT_LOST_WEBGL:
              return 'CONTEXT_LOST_WEBGL';
            default:
              return 'UNKNOWN_ERROR';
          }
        },
        dispose: function() {
          this.canvas && ((this.canvas = null), (this.gl = null)),
            this.clearWebGLCaches();
        },
        clearWebGLCaches: function() {
          (this.programCache = {}), (this.textureCache = {});
        },
        createTexture: function(t, e, i, r) {
          var n = t.createTexture();
          return (
            t.bindTexture(t.TEXTURE_2D, n),
            t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MAG_FILTER, t.NEAREST),
            t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MIN_FILTER, t.NEAREST),
            t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_S, t.CLAMP_TO_EDGE),
            t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_T, t.CLAMP_TO_EDGE),
            r
              ? t.texImage2D(
                  t.TEXTURE_2D,
                  0,
                  t.RGBA,
                  t.RGBA,
                  t.UNSIGNED_BYTE,
                  r
                )
              : t.texImage2D(
                  t.TEXTURE_2D,
                  0,
                  t.RGBA,
                  e,
                  i,
                  0,
                  t.RGBA,
                  t.UNSIGNED_BYTE,
                  null
                ),
            n
          );
        },
        getCachedTexture: function(t, e) {
          if (this.textureCache[t]) return this.textureCache[t];
          var i = this.createTexture(this.gl, e.width, e.height, e);
          return (this.textureCache[t] = i);
        },
        evictCachesForKey: function(t) {
          this.textureCache[t] &&
            (this.gl.deleteTexture(this.textureCache[t]),
            delete this.textureCache[t]);
        },
        copyGLTo2D: copyGLTo2DDrawImage,
        captureGPUInfo: function() {
          if (this.gpuInfo) return this.gpuInfo;
          var t = this.gl,
            e = t.getExtension('WEBGL_debug_renderer_info'),
            i = { renderer: '', vendor: '' };
          if (e) {
            var r = t.getParameter(e.UNMASKED_RENDERER_WEBGL),
              n = t.getParameter(e.UNMASKED_VENDOR_WEBGL);
            r && (i.renderer = r.toLowerCase()),
              n && (i.vendor = n.toLowerCase());
          }
          return (this.gpuInfo = i);
        },
      });
  })(),
  (function() {
    'use strict';
    var t = function() {};
    function e() {}
    (fabric.Canvas2dFilterBackend = e).prototype = {
      evictCachesForKey: t,
      dispose: t,
      clearWebGLCaches: t,
      resources: {},
      applyFilters: function(t, e, i, r, n) {
        var s = n.getContext('2d');
        s.drawImage(e, 0, 0, i, r);
        var o = {
          sourceWidth: i,
          sourceHeight: r,
          imageData: s.getImageData(0, 0, i, r),
          originalEl: e,
          originalImageData: s.getImageData(0, 0, i, r),
          canvasEl: n,
          ctx: s,
          filterBackend: this,
        };
        return (
          t.forEach(function(t) {
            t.applyTo(o);
          }),
          (o.imageData.width === i && o.imageData.height === r) ||
            ((n.width = o.imageData.width), (n.height = o.imageData.height)),
          s.putImageData(o.imageData, 0, 0),
          o
        );
      },
    };
  })(),
  (fabric.Image = fabric.Image || {}),
  (fabric.Image.filters = fabric.Image.filters || {}),
  (fabric.Image.filters.BaseFilter = fabric.util.createClass({
    type: 'BaseFilter',
    vertexSource:
      'attribute vec2 aPosition;\nvarying vec2 vTexCoord;\nvoid main() {\nvTexCoord = aPosition;\ngl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n}',
    fragmentSource:
      'precision highp float;\nvarying vec2 vTexCoord;\nuniform sampler2D uTexture;\nvoid main() {\ngl_FragColor = texture2D(uTexture, vTexCoord);\n}',
    initialize: function(t) {
      t && this.setOptions(t);
    },
    setOptions: function(t) {
      for (var e in t) this[e] = t[e];
    },
    createProgram: function(t, e, i) {
      (e = e || this.fragmentSource),
        (i = i || this.vertexSource),
        'highp' !== fabric.webGlPrecision &&
          (e = e.replace(
            /precision highp float/g,
            'precision ' + fabric.webGlPrecision + ' float'
          ));
      var r = t.createShader(t.VERTEX_SHADER);
      if (
        (t.shaderSource(r, i),
        t.compileShader(r),
        !t.getShaderParameter(r, t.COMPILE_STATUS))
      )
        throw new Error(
          'Vertex shader compile error for ' +
            this.type +
            ': ' +
            t.getShaderInfoLog(r)
        );
      var n = t.createShader(t.FRAGMENT_SHADER);
      if (
        (t.shaderSource(n, e),
        t.compileShader(n),
        !t.getShaderParameter(n, t.COMPILE_STATUS))
      )
        throw new Error(
          'Fragment shader compile error for ' +
            this.type +
            ': ' +
            t.getShaderInfoLog(n)
        );
      var s = t.createProgram();
      if (
        (t.attachShader(s, r),
        t.attachShader(s, n),
        t.linkProgram(s),
        !t.getProgramParameter(s, t.LINK_STATUS))
      )
        throw new Error(
          'Shader link error for "${this.type}" ' + t.getProgramInfoLog(s)
        );
      var o = this.getAttributeLocations(t, s),
        a = this.getUniformLocations(t, s) || {};
      return (
        (a.uStepW = t.getUniformLocation(s, 'uStepW')),
        (a.uStepH = t.getUniformLocation(s, 'uStepH')),
        { program: s, attributeLocations: o, uniformLocations: a }
      );
    },
    getAttributeLocations: function(t, e) {
      return { aPosition: t.getAttribLocation(e, 'aPosition') };
    },
    getUniformLocations: function() {
      return {};
    },
    sendAttributeData: function(t, e, i) {
      var r = e.aPosition,
        n = t.createBuffer();
      t.bindBuffer(t.ARRAY_BUFFER, n),
        t.enableVertexAttribArray(r),
        t.vertexAttribPointer(r, 2, t.FLOAT, !1, 0, 0),
        t.bufferData(t.ARRAY_BUFFER, i, t.STATIC_DRAW);
    },
    _setupFrameBuffer: function(t) {
      var e,
        i,
        r = t.context;
      1 < t.passes
        ? ((e = t.destinationWidth),
          (i = t.destinationHeight),
          (t.sourceWidth === e && t.sourceHeight === i) ||
            (r.deleteTexture(t.targetTexture),
            (t.targetTexture = t.filterBackend.createTexture(r, e, i))),
          r.framebufferTexture2D(
            r.FRAMEBUFFER,
            r.COLOR_ATTACHMENT0,
            r.TEXTURE_2D,
            t.targetTexture,
            0
          ))
        : (r.bindFramebuffer(r.FRAMEBUFFER, null), r.finish());
    },
    _swapTextures: function(t) {
      t.passes--, t.pass++;
      var e = t.targetTexture;
      (t.targetTexture = t.sourceTexture), (t.sourceTexture = e);
    },
    isNeutralState: function() {
      var t = this.mainParameter,
        e = fabric.Image.filters[this.type].prototype;
      if (t) {
        if (Array.isArray(e[t])) {
          for (var i = e[t].length; i--; )
            if (this[t][i] !== e[t][i]) return !1;
          return !0;
        }
        return e[t] === this[t];
      }
      return !1;
    },
    applyTo: function(t) {
      t.webgl
        ? (this._setupFrameBuffer(t),
          this.applyToWebGL(t),
          this._swapTextures(t))
        : this.applyTo2d(t);
    },
    retrieveShader: function(t) {
      return (
        t.programCache.hasOwnProperty(this.type) ||
          (t.programCache[this.type] = this.createProgram(t.context)),
        t.programCache[this.type]
      );
    },
    applyToWebGL: function(t) {
      var e = t.context,
        i = this.retrieveShader(t);
      0 === t.pass && t.originalTexture
        ? e.bindTexture(e.TEXTURE_2D, t.originalTexture)
        : e.bindTexture(e.TEXTURE_2D, t.sourceTexture),
        e.useProgram(i.program),
        this.sendAttributeData(e, i.attributeLocations, t.aPosition),
        e.uniform1f(i.uniformLocations.uStepW, 1 / t.sourceWidth),
        e.uniform1f(i.uniformLocations.uStepH, 1 / t.sourceHeight),
        this.sendUniformData(e, i.uniformLocations),
        e.viewport(0, 0, t.destinationWidth, t.destinationHeight),
        e.drawArrays(e.TRIANGLE_STRIP, 0, 4);
    },
    bindAdditionalTexture: function(t, e, i) {
      t.activeTexture(i),
        t.bindTexture(t.TEXTURE_2D, e),
        t.activeTexture(t.TEXTURE0);
    },
    unbindAdditionalTexture: function(t, e) {
      t.activeTexture(e),
        t.bindTexture(t.TEXTURE_2D, null),
        t.activeTexture(t.TEXTURE0);
    },
    getMainParameter: function() {
      return this[this.mainParameter];
    },
    setMainParameter: function(t) {
      this[this.mainParameter] = t;
    },
    sendUniformData: function() {},
    createHelpLayer: function(t) {
      if (!t.helpLayer) {
        var e = document.createElement('canvas');
        (e.width = t.sourceWidth),
          (e.height = t.sourceHeight),
          (t.helpLayer = e);
      }
    },
    toObject: function() {
      var t = { type: this.type },
        e = this.mainParameter;
      return e && (t[e] = this[e]), t;
    },
    toJSON: function() {
      return this.toObject();
    },
  })),
  (fabric.Image.filters.BaseFilter.fromObject = function(t, e) {
    var i = new fabric.Image.filters[t.type](t);
    return e && e(i), i;
  }),
  (function(t) {
    'use strict';
    var e = t.fabric || (t.fabric = {}),
      i = e.Image.filters,
      r = e.util.createClass;
    (i.ColorMatrix = r(i.BaseFilter, {
      type: 'ColorMatrix',
      fragmentSource:
        'precision highp float;\nuniform sampler2D uTexture;\nvarying vec2 vTexCoord;\nuniform mat4 uColorMatrix;\nuniform vec4 uConstants;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ncolor *= uColorMatrix;\ncolor += uConstants;\ngl_FragColor = color;\n}',
      matrix: [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],
      mainParameter: 'matrix',
      colorsOnly: !0,
      initialize: function(t) {
        this.callSuper('initialize', t), (this.matrix = this.matrix.slice(0));
      },
      applyTo2d: function(t) {
        var e,
          i,
          r,
          n,
          s,
          o = t.imageData.data,
          a = o.length,
          h = this.matrix,
          c = this.colorsOnly;
        for (s = 0; s < a; s += 4)
          (e = o[s]),
            (i = o[s + 1]),
            (r = o[s + 2]),
            c
              ? ((o[s] = e * h[0] + i * h[1] + r * h[2] + 255 * h[4]),
                (o[s + 1] = e * h[5] + i * h[6] + r * h[7] + 255 * h[9]),
                (o[s + 2] = e * h[10] + i * h[11] + r * h[12] + 255 * h[14]))
              : ((n = o[s + 3]),
                (o[s] = e * h[0] + i * h[1] + r * h[2] + n * h[3] + 255 * h[4]),
                (o[s + 1] =
                  e * h[5] + i * h[6] + r * h[7] + n * h[8] + 255 * h[9]),
                (o[s + 2] =
                  e * h[10] + i * h[11] + r * h[12] + n * h[13] + 255 * h[14]),
                (o[s + 3] =
                  e * h[15] + i * h[16] + r * h[17] + n * h[18] + 255 * h[19]));
      },
      getUniformLocations: function(t, e) {
        return {
          uColorMatrix: t.getUniformLocation(e, 'uColorMatrix'),
          uConstants: t.getUniformLocation(e, 'uConstants'),
        };
      },
      sendUniformData: function(t, e) {
        var i = this.matrix,
          r = [
            i[0],
            i[1],
            i[2],
            i[3],
            i[5],
            i[6],
            i[7],
            i[8],
            i[10],
            i[11],
            i[12],
            i[13],
            i[15],
            i[16],
            i[17],
            i[18],
          ],
          n = [i[4], i[9], i[14], i[19]];
        t.uniformMatrix4fv(e.uColorMatrix, !1, r),
          t.uniform4fv(e.uConstants, n);
      },
    })),
      (e.Image.filters.ColorMatrix.fromObject =
        e.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var e = t.fabric || (t.fabric = {}),
      i = e.Image.filters,
      r = e.util.createClass;
    (i.Brightness = r(i.BaseFilter, {
      type: 'Brightness',
      fragmentSource:
        'precision highp float;\nuniform sampler2D uTexture;\nuniform float uBrightness;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ncolor.rgb += uBrightness;\ngl_FragColor = color;\n}',
      brightness: 0,
      mainParameter: 'brightness',
      applyTo2d: function(t) {
        if (0 !== this.brightness) {
          var e,
            i = t.imageData.data,
            r = i.length,
            n = Math.round(255 * this.brightness);
          for (e = 0; e < r; e += 4)
            (i[e] = i[e] + n),
              (i[e + 1] = i[e + 1] + n),
              (i[e + 2] = i[e + 2] + n);
        }
      },
      getUniformLocations: function(t, e) {
        return { uBrightness: t.getUniformLocation(e, 'uBrightness') };
      },
      sendUniformData: function(t, e) {
        t.uniform1f(e.uBrightness, this.brightness);
      },
    })),
      (e.Image.filters.Brightness.fromObject =
        e.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var e = t.fabric || (t.fabric = {}),
      i = e.util.object.extend,
      r = e.Image.filters,
      n = e.util.createClass;
    (r.Convolute = n(r.BaseFilter, {
      type: 'Convolute',
      opaque: !1,
      matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0],
      fragmentSource: {
        Convolute_3_1:
          'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[9];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 0);\nfor (float h = 0.0; h < 3.0; h+=1.0) {\nfor (float w = 0.0; w < 3.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\ncolor += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n}\n}\ngl_FragColor = color;\n}',
        Convolute_3_0:
          'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[9];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 1);\nfor (float h = 0.0; h < 3.0; h+=1.0) {\nfor (float w = 0.0; w < 3.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\ncolor.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n}\n}\nfloat alpha = texture2D(uTexture, vTexCoord).a;\ngl_FragColor = color;\ngl_FragColor.a = alpha;\n}',
        Convolute_5_1:
          'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[25];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 0);\nfor (float h = 0.0; h < 5.0; h+=1.0) {\nfor (float w = 0.0; w < 5.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\ncolor += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n}\n}\ngl_FragColor = color;\n}',
        Convolute_5_0:
          'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[25];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 1);\nfor (float h = 0.0; h < 5.0; h+=1.0) {\nfor (float w = 0.0; w < 5.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\ncolor.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n}\n}\nfloat alpha = texture2D(uTexture, vTexCoord).a;\ngl_FragColor = color;\ngl_FragColor.a = alpha;\n}',
        Convolute_7_1:
          'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[49];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 0);\nfor (float h = 0.0; h < 7.0; h+=1.0) {\nfor (float w = 0.0; w < 7.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\ncolor += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n}\n}\ngl_FragColor = color;\n}',
        Convolute_7_0:
          'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[49];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 1);\nfor (float h = 0.0; h < 7.0; h+=1.0) {\nfor (float w = 0.0; w < 7.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\ncolor.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n}\n}\nfloat alpha = texture2D(uTexture, vTexCoord).a;\ngl_FragColor = color;\ngl_FragColor.a = alpha;\n}',
        Convolute_9_1:
          'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[81];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 0);\nfor (float h = 0.0; h < 9.0; h+=1.0) {\nfor (float w = 0.0; w < 9.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\ncolor += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n}\n}\ngl_FragColor = color;\n}',
        Convolute_9_0:
          'precision highp float;\nuniform sampler2D uTexture;\nuniform float uMatrix[81];\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = vec4(0, 0, 0, 1);\nfor (float h = 0.0; h < 9.0; h+=1.0) {\nfor (float w = 0.0; w < 9.0; w+=1.0) {\nvec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\ncolor.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n}\n}\nfloat alpha = texture2D(uTexture, vTexCoord).a;\ngl_FragColor = color;\ngl_FragColor.a = alpha;\n}',
      },
      retrieveShader: function(t) {
        var e = Math.sqrt(this.matrix.length),
          i = this.type + '_' + e + '_' + (this.opaque ? 1 : 0),
          r = this.fragmentSource[i];
        return (
          t.programCache.hasOwnProperty(i) ||
            (t.programCache[i] = this.createProgram(t.context, r)),
          t.programCache[i]
        );
      },
      applyTo2d: function(t) {
        var e,
          i,
          r,
          n,
          s,
          o,
          a,
          h,
          c,
          l,
          u,
          f,
          d,
          g = t.imageData,
          p = g.data,
          v = this.matrix,
          m = Math.round(Math.sqrt(v.length)),
          b = Math.floor(m / 2),
          _ = g.width,
          y = g.height,
          x = t.ctx.createImageData(_, y),
          C = x.data,
          S = this.opaque ? 1 : 0;
        for (u = 0; u < y; u++)
          for (l = 0; l < _; l++) {
            for (s = 4 * (u * _ + l), d = n = r = i = e = 0; d < m; d++)
              for (f = 0; f < m; f++)
                (o = l + f - b),
                  (a = u + d - b) < 0 ||
                    y < a ||
                    o < 0 ||
                    _ < o ||
                    ((h = 4 * (a * _ + o)),
                    (c = v[d * m + f]),
                    (e += p[h] * c),
                    (i += p[h + 1] * c),
                    (r += p[h + 2] * c),
                    S || (n += p[h + 3] * c));
            (C[s] = e),
              (C[s + 1] = i),
              (C[s + 2] = r),
              (C[s + 3] = S ? p[s + 3] : n);
          }
        t.imageData = x;
      },
      getUniformLocations: function(t, e) {
        return {
          uMatrix: t.getUniformLocation(e, 'uMatrix'),
          uOpaque: t.getUniformLocation(e, 'uOpaque'),
          uHalfSize: t.getUniformLocation(e, 'uHalfSize'),
          uSize: t.getUniformLocation(e, 'uSize'),
        };
      },
      sendUniformData: function(t, e) {
        t.uniform1fv(e.uMatrix, this.matrix);
      },
      toObject: function() {
        return i(this.callSuper('toObject'), {
          opaque: this.opaque,
          matrix: this.matrix,
        });
      },
    })),
      (e.Image.filters.Convolute.fromObject =
        e.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var e = t.fabric || (t.fabric = {}),
      i = e.Image.filters,
      r = e.util.createClass;
    (i.Grayscale = r(i.BaseFilter, {
      type: 'Grayscale',
      fragmentSource: {
        average:
          'precision highp float;\nuniform sampler2D uTexture;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat average = (color.r + color.b + color.g) / 3.0;\ngl_FragColor = vec4(average, average, average, color.a);\n}',
        lightness:
          'precision highp float;\nuniform sampler2D uTexture;\nuniform int uMode;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 col = texture2D(uTexture, vTexCoord);\nfloat average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\ngl_FragColor = vec4(average, average, average, col.a);\n}',
        luminosity:
          'precision highp float;\nuniform sampler2D uTexture;\nuniform int uMode;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 col = texture2D(uTexture, vTexCoord);\nfloat average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\ngl_FragColor = vec4(average, average, average, col.a);\n}',
      },
      mode: 'average',
      mainParameter: 'mode',
      applyTo2d: function(t) {
        var e,
          i,
          r = t.imageData.data,
          n = r.length,
          s = this.mode;
        for (e = 0; e < n; e += 4)
          'average' === s
            ? (i = (r[e] + r[e + 1] + r[e + 2]) / 3)
            : 'lightness' === s
            ? (i =
                (Math.min(r[e], r[e + 1], r[e + 2]) +
                  Math.max(r[e], r[e + 1], r[e + 2])) /
                2)
            : 'luminosity' === s &&
              (i = 0.21 * r[e] + 0.72 * r[e + 1] + 0.07 * r[e + 2]),
            (r[e] = i),
            (r[e + 1] = i),
            (r[e + 2] = i);
      },
      retrieveShader: function(t) {
        var e = this.type + '_' + this.mode;
        if (!t.programCache.hasOwnProperty(e)) {
          var i = this.fragmentSource[this.mode];
          t.programCache[e] = this.createProgram(t.context, i);
        }
        return t.programCache[e];
      },
      getUniformLocations: function(t, e) {
        return { uMode: t.getUniformLocation(e, 'uMode') };
      },
      sendUniformData: function(t, e) {
        t.uniform1i(e.uMode, 1);
      },
      isNeutralState: function() {
        return !1;
      },
    })),
      (e.Image.filters.Grayscale.fromObject =
        e.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var e = t.fabric || (t.fabric = {}),
      i = e.Image.filters,
      r = e.util.createClass;
    (i.Invert = r(i.BaseFilter, {
      type: 'Invert',
      fragmentSource:
        'precision highp float;\nuniform sampler2D uTexture;\nuniform int uInvert;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nif (uInvert == 1) {\ngl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n} else {\ngl_FragColor = color;\n}\n}',
      invert: !0,
      mainParameter: 'invert',
      applyTo2d: function(t) {
        var e,
          i = t.imageData.data,
          r = i.length;
        for (e = 0; e < r; e += 4)
          (i[e] = 255 - i[e]),
            (i[e + 1] = 255 - i[e + 1]),
            (i[e + 2] = 255 - i[e + 2]);
      },
      isNeutralState: function() {
        return !this.invert;
      },
      getUniformLocations: function(t, e) {
        return { uInvert: t.getUniformLocation(e, 'uInvert') };
      },
      sendUniformData: function(t, e) {
        t.uniform1i(e.uInvert, this.invert);
      },
    })),
      (e.Image.filters.Invert.fromObject =
        e.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var e = t.fabric || (t.fabric = {}),
      i = e.util.object.extend,
      r = e.Image.filters,
      n = e.util.createClass;
    (r.Noise = n(r.BaseFilter, {
      type: 'Noise',
      fragmentSource:
        'precision highp float;\nuniform sampler2D uTexture;\nuniform float uStepH;\nuniform float uNoise;\nuniform float uSeed;\nvarying vec2 vTexCoord;\nfloat rand(vec2 co, float seed, float vScale) {\nreturn fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n}\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ncolor.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\ngl_FragColor = color;\n}',
      mainParameter: 'noise',
      noise: 0,
      applyTo2d: function(t) {
        if (0 !== this.noise) {
          var e,
            i,
            r = t.imageData.data,
            n = r.length,
            s = this.noise;
          for (e = 0, n = r.length; e < n; e += 4)
            (i = (0.5 - Math.random()) * s),
              (r[e] += i),
              (r[e + 1] += i),
              (r[e + 2] += i);
        }
      },
      getUniformLocations: function(t, e) {
        return {
          uNoise: t.getUniformLocation(e, 'uNoise'),
          uSeed: t.getUniformLocation(e, 'uSeed'),
        };
      },
      sendUniformData: function(t, e) {
        t.uniform1f(e.uNoise, this.noise / 255),
          t.uniform1f(e.uSeed, Math.random());
      },
      toObject: function() {
        return i(this.callSuper('toObject'), { noise: this.noise });
      },
    })),
      (e.Image.filters.Noise.fromObject =
        e.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var e = t.fabric || (t.fabric = {}),
      i = e.Image.filters,
      r = e.util.createClass;
    (i.Pixelate = r(i.BaseFilter, {
      type: 'Pixelate',
      blocksize: 4,
      mainParameter: 'blocksize',
      fragmentSource:
        'precision highp float;\nuniform sampler2D uTexture;\nuniform float uBlocksize;\nuniform float uStepW;\nuniform float uStepH;\nvarying vec2 vTexCoord;\nvoid main() {\nfloat blockW = uBlocksize * uStepW;\nfloat blockH = uBlocksize * uStepW;\nint posX = int(vTexCoord.x / blockW);\nint posY = int(vTexCoord.y / blockH);\nfloat fposX = float(posX);\nfloat fposY = float(posY);\nvec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\nvec4 color = texture2D(uTexture, squareCoords);\ngl_FragColor = color;\n}',
      applyTo2d: function(t) {
        var e,
          i,
          r,
          n,
          s,
          o,
          a,
          h,
          c,
          l,
          u,
          f = t.imageData,
          d = f.data,
          g = f.height,
          p = f.width;
        for (i = 0; i < g; i += this.blocksize)
          for (r = 0; r < p; r += this.blocksize)
            for (
              n = d[(e = 4 * i * p + 4 * r)],
                s = d[e + 1],
                o = d[e + 2],
                a = d[e + 3],
                l = Math.min(i + this.blocksize, g),
                u = Math.min(r + this.blocksize, p),
                h = i;
              h < l;
              h++
            )
              for (c = r; c < u; c++)
                (d[(e = 4 * h * p + 4 * c)] = n),
                  (d[e + 1] = s),
                  (d[e + 2] = o),
                  (d[e + 3] = a);
      },
      isNeutralState: function() {
        return 1 === this.blocksize;
      },
      getUniformLocations: function(t, e) {
        return {
          uBlocksize: t.getUniformLocation(e, 'uBlocksize'),
          uStepW: t.getUniformLocation(e, 'uStepW'),
          uStepH: t.getUniformLocation(e, 'uStepH'),
        };
      },
      sendUniformData: function(t, e) {
        t.uniform1f(e.uBlocksize, this.blocksize);
      },
    })),
      (e.Image.filters.Pixelate.fromObject =
        e.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var l = t.fabric || (t.fabric = {}),
      e = l.util.object.extend,
      i = l.Image.filters,
      r = l.util.createClass;
    (i.RemoveColor = r(i.BaseFilter, {
      type: 'RemoveColor',
      color: '#FFFFFF',
      fragmentSource:
        'precision highp float;\nuniform sampler2D uTexture;\nuniform vec4 uLow;\nuniform vec4 uHigh;\nvarying vec2 vTexCoord;\nvoid main() {\ngl_FragColor = texture2D(uTexture, vTexCoord);\nif(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\ngl_FragColor.a = 0.0;\n}\n}',
      distance: 0.02,
      useAlpha: !1,
      applyTo2d: function(t) {
        var e,
          i,
          r,
          n,
          s = t.imageData.data,
          o = 255 * this.distance,
          a = new l.Color(this.color).getSource(),
          h = [a[0] - o, a[1] - o, a[2] - o],
          c = [a[0] + o, a[1] + o, a[2] + o];
        for (e = 0; e < s.length; e += 4)
          (i = s[e]),
            (r = s[e + 1]),
            (n = s[e + 2]),
            h[0] < i &&
              h[1] < r &&
              h[2] < n &&
              i < c[0] &&
              r < c[1] &&
              n < c[2] &&
              (s[e + 3] = 0);
      },
      getUniformLocations: function(t, e) {
        return {
          uLow: t.getUniformLocation(e, 'uLow'),
          uHigh: t.getUniformLocation(e, 'uHigh'),
        };
      },
      sendUniformData: function(t, e) {
        var i = new l.Color(this.color).getSource(),
          r = parseFloat(this.distance),
          n = [0 + i[0] / 255 - r, 0 + i[1] / 255 - r, 0 + i[2] / 255 - r, 1],
          s = [i[0] / 255 + r, i[1] / 255 + r, i[2] / 255 + r, 1];
        t.uniform4fv(e.uLow, n), t.uniform4fv(e.uHigh, s);
      },
      toObject: function() {
        return e(this.callSuper('toObject'), {
          color: this.color,
          distance: this.distance,
        });
      },
    })),
      (l.Image.filters.RemoveColor.fromObject =
        l.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var e = t.fabric || (t.fabric = {}),
      i = e.Image.filters,
      r = e.util.createClass,
      n = {
        Brownie: [
          0.5997,
          0.34553,
          -0.27082,
          0,
          0.186,
          -0.0377,
          0.86095,
          0.15059,
          0,
          -0.1449,
          0.24113,
          -0.07441,
          0.44972,
          0,
          -0.02965,
          0,
          0,
          0,
          1,
          0,
        ],
        Vintage: [
          0.62793,
          0.32021,
          -0.03965,
          0,
          0.03784,
          0.02578,
          0.64411,
          0.03259,
          0,
          0.02926,
          0.0466,
          -0.08512,
          0.52416,
          0,
          0.02023,
          0,
          0,
          0,
          1,
          0,
        ],
        Kodachrome: [
          1.12855,
          -0.39673,
          -0.03992,
          0,
          0.24991,
          -0.16404,
          1.08352,
          -0.05498,
          0,
          0.09698,
          -0.16786,
          -0.56034,
          1.60148,
          0,
          0.13972,
          0,
          0,
          0,
          1,
          0,
        ],
        Technicolor: [
          1.91252,
          -0.85453,
          -0.09155,
          0,
          0.04624,
          -0.30878,
          1.76589,
          -0.10601,
          0,
          -0.27589,
          -0.2311,
          -0.75018,
          1.84759,
          0,
          0.12137,
          0,
          0,
          0,
          1,
          0,
        ],
        Polaroid: [
          1.438,
          -0.062,
          -0.062,
          0,
          0,
          -0.122,
          1.378,
          -0.122,
          0,
          0,
          -0.016,
          -0.016,
          1.483,
          0,
          0,
          0,
          0,
          0,
          1,
          0,
        ],
        Sepia: [
          0.393,
          0.769,
          0.189,
          0,
          0,
          0.349,
          0.686,
          0.168,
          0,
          0,
          0.272,
          0.534,
          0.131,
          0,
          0,
          0,
          0,
          0,
          1,
          0,
        ],
        BlackWhite: [
          1.5,
          1.5,
          1.5,
          0,
          -1,
          1.5,
          1.5,
          1.5,
          0,
          -1,
          1.5,
          1.5,
          1.5,
          0,
          -1,
          0,
          0,
          0,
          1,
          0,
        ],
      };
    for (var s in n)
      (i[s] = r(i.ColorMatrix, {
        type: s,
        matrix: n[s],
        mainParameter: !1,
        colorsOnly: !0,
      })),
        (e.Image.filters[s].fromObject = e.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var f = t.fabric,
      e = f.Image.filters,
      i = f.util.createClass;
    (e.BlendColor = i(e.BaseFilter, {
      type: 'BlendColor',
      color: '#F95C63',
      mode: 'multiply',
      alpha: 1,
      fragmentSource: {
        multiply: 'gl_FragColor.rgb *= uColor.rgb;\n',
        screen:
          'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n',
        add: 'gl_FragColor.rgb += uColor.rgb;\n',
        diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n',
        subtract: 'gl_FragColor.rgb -= uColor.rgb;\n',
        lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n',
        darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n',
        exclusion:
          'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n',
        overlay:
          'if (uColor.r < 0.5) {\ngl_FragColor.r *= 2.0 * uColor.r;\n} else {\ngl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n}\nif (uColor.g < 0.5) {\ngl_FragColor.g *= 2.0 * uColor.g;\n} else {\ngl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n}\nif (uColor.b < 0.5) {\ngl_FragColor.b *= 2.0 * uColor.b;\n} else {\ngl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n}\n',
        tint:
          'gl_FragColor.rgb *= (1.0 - uColor.a);\ngl_FragColor.rgb += uColor.rgb;\n',
      },
      buildSource: function(t) {
        return (
          'precision highp float;\nuniform sampler2D uTexture;\nuniform vec4 uColor;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\ngl_FragColor = color;\nif (color.a > 0.0) {\n' +
          this.fragmentSource[t] +
          '}\n}'
        );
      },
      retrieveShader: function(t) {
        var e,
          i = this.type + '_' + this.mode;
        return (
          t.programCache.hasOwnProperty(i) ||
            ((e = this.buildSource(this.mode)),
            (t.programCache[i] = this.createProgram(t.context, e))),
          t.programCache[i]
        );
      },
      applyTo2d: function(t) {
        var e,
          i,
          r,
          n,
          s,
          o,
          a,
          h = t.imageData.data,
          c = h.length,
          l = 1 - this.alpha;
        (e = (a = new f.Color(this.color).getSource())[0] * this.alpha),
          (i = a[1] * this.alpha),
          (r = a[2] * this.alpha);
        for (var u = 0; u < c; u += 4)
          switch (((n = h[u]), (s = h[u + 1]), (o = h[u + 2]), this.mode)) {
            case 'multiply':
              (h[u] = (n * e) / 255),
                (h[u + 1] = (s * i) / 255),
                (h[u + 2] = (o * r) / 255);
              break;
            case 'screen':
              (h[u] = 255 - ((255 - n) * (255 - e)) / 255),
                (h[u + 1] = 255 - ((255 - s) * (255 - i)) / 255),
                (h[u + 2] = 255 - ((255 - o) * (255 - r)) / 255);
              break;
            case 'add':
              (h[u] = n + e), (h[u + 1] = s + i), (h[u + 2] = o + r);
              break;
            case 'diff':
            case 'difference':
              (h[u] = Math.abs(n - e)),
                (h[u + 1] = Math.abs(s - i)),
                (h[u + 2] = Math.abs(o - r));
              break;
            case 'subtract':
              (h[u] = n - e), (h[u + 1] = s - i), (h[u + 2] = o - r);
              break;
            case 'darken':
              (h[u] = Math.min(n, e)),
                (h[u + 1] = Math.min(s, i)),
                (h[u + 2] = Math.min(o, r));
              break;
            case 'lighten':
              (h[u] = Math.max(n, e)),
                (h[u + 1] = Math.max(s, i)),
                (h[u + 2] = Math.max(o, r));
              break;
            case 'overlay':
              (h[u] =
                e < 128
                  ? (2 * n * e) / 255
                  : 255 - (2 * (255 - n) * (255 - e)) / 255),
                (h[u + 1] =
                  i < 128
                    ? (2 * s * i) / 255
                    : 255 - (2 * (255 - s) * (255 - i)) / 255),
                (h[u + 2] =
                  r < 128
                    ? (2 * o * r) / 255
                    : 255 - (2 * (255 - o) * (255 - r)) / 255);
              break;
            case 'exclusion':
              (h[u] = e + n - (2 * e * n) / 255),
                (h[u + 1] = i + s - (2 * i * s) / 255),
                (h[u + 2] = r + o - (2 * r * o) / 255);
              break;
            case 'tint':
              (h[u] = e + n * l),
                (h[u + 1] = i + s * l),
                (h[u + 2] = r + o * l);
          }
      },
      getUniformLocations: function(t, e) {
        return { uColor: t.getUniformLocation(e, 'uColor') };
      },
      sendUniformData: function(t, e) {
        var i = new f.Color(this.color).getSource();
        (i[0] = (this.alpha * i[0]) / 255),
          (i[1] = (this.alpha * i[1]) / 255),
          (i[2] = (this.alpha * i[2]) / 255),
          (i[3] = this.alpha),
          t.uniform4fv(e.uColor, i);
      },
      toObject: function() {
        return {
          type: this.type,
          color: this.color,
          mode: this.mode,
          alpha: this.alpha,
        };
      },
    })),
      (f.Image.filters.BlendColor.fromObject =
        f.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var y = t.fabric,
      e = y.Image.filters,
      i = y.util.createClass;
    (e.BlendImage = i(e.BaseFilter, {
      type: 'BlendImage',
      image: null,
      mode: 'multiply',
      alpha: 1,
      vertexSource:
        'attribute vec2 aPosition;\nvarying vec2 vTexCoord;\nvarying vec2 vTexCoord2;\nuniform mat3 uTransformMatrix;\nvoid main() {\nvTexCoord = aPosition;\nvTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\ngl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n}',
      fragmentSource: {
        multiply:
          'precision highp float;\nuniform sampler2D uTexture;\nuniform sampler2D uImage;\nuniform vec4 uColor;\nvarying vec2 vTexCoord;\nvarying vec2 vTexCoord2;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nvec4 color2 = texture2D(uImage, vTexCoord2);\ncolor.rgba *= color2.rgba;\ngl_FragColor = color;\n}',
        mask:
          'precision highp float;\nuniform sampler2D uTexture;\nuniform sampler2D uImage;\nuniform vec4 uColor;\nvarying vec2 vTexCoord;\nvarying vec2 vTexCoord2;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nvec4 color2 = texture2D(uImage, vTexCoord2);\ncolor.a = color2.a;\ngl_FragColor = color;\n}',
      },
      retrieveShader: function(t) {
        var e = this.type + '_' + this.mode,
          i = this.fragmentSource[this.mode];
        return (
          t.programCache.hasOwnProperty(e) ||
            (t.programCache[e] = this.createProgram(t.context, i)),
          t.programCache[e]
        );
      },
      applyToWebGL: function(t) {
        var e = t.context,
          i = this.createTexture(t.filterBackend, this.image);
        this.bindAdditionalTexture(e, i, e.TEXTURE1),
          this.callSuper('applyToWebGL', t),
          this.unbindAdditionalTexture(e, e.TEXTURE1);
      },
      createTexture: function(t, e) {
        return t.getCachedTexture(e.cacheKey, e._element);
      },
      calculateMatrix: function() {
        var t = this.image,
          e = t._element.width,
          i = t._element.height;
        return [
          1 / t.scaleX,
          0,
          0,
          0,
          1 / t.scaleY,
          0,
          -t.left / e,
          -t.top / i,
          1,
        ];
      },
      applyTo2d: function(t) {
        var e,
          i,
          r,
          n,
          s,
          o,
          a,
          h,
          c,
          l,
          u,
          f = t.imageData,
          d = t.filterBackend.resources,
          g = f.data,
          p = g.length,
          v = f.width,
          m = f.height,
          b = this.image;
        d.blendImage || (d.blendImage = y.util.createCanvasElement()),
          (l = (c = d.blendImage).getContext('2d')),
          c.width !== v || c.height !== m
            ? ((c.width = v), (c.height = m))
            : l.clearRect(0, 0, v, m),
          l.setTransform(b.scaleX, 0, 0, b.scaleY, b.left, b.top),
          l.drawImage(b._element, 0, 0, v, m),
          (u = l.getImageData(0, 0, v, m).data);
        for (var _ = 0; _ < p; _ += 4)
          switch (
            ((s = g[_]),
            (o = g[_ + 1]),
            (a = g[_ + 2]),
            (h = g[_ + 3]),
            (e = u[_]),
            (i = u[_ + 1]),
            (r = u[_ + 2]),
            (n = u[_ + 3]),
            this.mode)
          ) {
            case 'multiply':
              (g[_] = (s * e) / 255),
                (g[_ + 1] = (o * i) / 255),
                (g[_ + 2] = (a * r) / 255),
                (g[_ + 3] = (h * n) / 255);
              break;
            case 'mask':
              g[_ + 3] = n;
          }
      },
      getUniformLocations: function(t, e) {
        return {
          uTransformMatrix: t.getUniformLocation(e, 'uTransformMatrix'),
          uImage: t.getUniformLocation(e, 'uImage'),
        };
      },
      sendUniformData: function(t, e) {
        var i = this.calculateMatrix();
        t.uniform1i(e.uImage, 1), t.uniformMatrix3fv(e.uTransformMatrix, !1, i);
      },
      toObject: function() {
        return {
          type: this.type,
          image: this.image && this.image.toObject(),
          mode: this.mode,
          alpha: this.alpha,
        };
      },
    })),
      (y.Image.filters.BlendImage.fromObject = function(i, r) {
        y.Image.fromObject(i.image, function(t) {
          var e = y.util.object.clone(i);
          (e.image = t), r(new y.Image.filters.BlendImage(e));
        });
      });
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var m = t.fabric || (t.fabric = {}),
      j = Math.pow,
      A = Math.floor,
      M = Math.sqrt,
      F = Math.abs,
      c = Math.round,
      r = Math.sin,
      I = Math.ceil,
      e = m.Image.filters,
      i = m.util.createClass;
    (e.Resize = i(e.BaseFilter, {
      type: 'Resize',
      resizeType: 'hermite',
      scaleX: 1,
      scaleY: 1,
      lanczosLobes: 3,
      getUniformLocations: function(t, e) {
        return {
          uDelta: t.getUniformLocation(e, 'uDelta'),
          uTaps: t.getUniformLocation(e, 'uTaps'),
        };
      },
      sendUniformData: function(t, e) {
        t.uniform2fv(
          e.uDelta,
          this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]
        ),
          t.uniform1fv(e.uTaps, this.taps);
      },
      retrieveShader: function(t) {
        var e = this.getFilterWindow(),
          i = this.type + '_' + e;
        if (!t.programCache.hasOwnProperty(i)) {
          var r = this.generateShader(e);
          t.programCache[i] = this.createProgram(t.context, r);
        }
        return t.programCache[i];
      },
      getFilterWindow: function() {
        var t = this.tempScale;
        return Math.ceil(this.lanczosLobes / t);
      },
      getTaps: function() {
        for (
          var t = this.lanczosCreate(this.lanczosLobes),
            e = this.tempScale,
            i = this.getFilterWindow(),
            r = new Array(i),
            n = 1;
          n <= i;
          n++
        )
          r[n - 1] = t(n * e);
        return r;
      },
      generateShader: function(t) {
        for (
          var e = new Array(t), i = this.fragmentSourceTOP, r = 1;
          r <= t;
          r++
        )
          e[r - 1] = r + '.0 * uDelta';
        return (
          (i += 'uniform float uTaps[' + t + '];\n'),
          (i += 'void main() {\n'),
          (i += '  vec4 color = texture2D(uTexture, vTexCoord);\n'),
          (i += '  float sum = 1.0;\n'),
          e.forEach(function(t, e) {
            (i +=
              '  color += texture2D(uTexture, vTexCoord + ' +
              t +
              ') * uTaps[' +
              e +
              '];\n'),
              (i +=
                '  color += texture2D(uTexture, vTexCoord - ' +
                t +
                ') * uTaps[' +
                e +
                '];\n'),
              (i += '  sum += 2.0 * uTaps[' + e + '];\n');
          }),
          (i += '  gl_FragColor = color / sum;\n'),
          (i += '}')
        );
      },
      fragmentSourceTOP:
        'precision highp float;\nuniform sampler2D uTexture;\nuniform vec2 uDelta;\nvarying vec2 vTexCoord;\n',
      applyTo: function(t) {
        t.webgl
          ? (t.passes++,
            (this.width = t.sourceWidth),
            (this.horizontal = !0),
            (this.dW = Math.round(this.width * this.scaleX)),
            (this.dH = t.sourceHeight),
            (this.tempScale = this.dW / this.width),
            (this.taps = this.getTaps()),
            (t.destinationWidth = this.dW),
            this._setupFrameBuffer(t),
            this.applyToWebGL(t),
            this._swapTextures(t),
            (t.sourceWidth = t.destinationWidth),
            (this.height = t.sourceHeight),
            (this.horizontal = !1),
            (this.dH = Math.round(this.height * this.scaleY)),
            (this.tempScale = this.dH / this.height),
            (this.taps = this.getTaps()),
            (t.destinationHeight = this.dH),
            this._setupFrameBuffer(t),
            this.applyToWebGL(t),
            this._swapTextures(t),
            (t.sourceHeight = t.destinationHeight))
          : this.applyTo2d(t);
      },
      isNeutralState: function() {
        return 1 === this.scaleX && 1 === this.scaleY;
      },
      lanczosCreate: function(i) {
        return function(t) {
          if (i <= t || t <= -i) return 0;
          if (t < 1.1920929e-7 && -1.1920929e-7 < t) return 1;
          var e = (t *= Math.PI) / i;
          return ((r(t) / t) * r(e)) / e;
        };
      },
      applyTo2d: function(t) {
        var e = t.imageData,
          i = this.scaleX,
          r = this.scaleY;
        (this.rcpScaleX = 1 / i), (this.rcpScaleY = 1 / r);
        var n,
          s = e.width,
          o = e.height,
          a = c(s * i),
          h = c(o * r);
        'sliceHack' === this.resizeType
          ? (n = this.sliceByTwo(t, s, o, a, h))
          : 'hermite' === this.resizeType
          ? (n = this.hermiteFastResize(t, s, o, a, h))
          : 'bilinear' === this.resizeType
          ? (n = this.bilinearFiltering(t, s, o, a, h))
          : 'lanczos' === this.resizeType &&
            (n = this.lanczosResize(t, s, o, a, h)),
          (t.imageData = n);
      },
      sliceByTwo: function(t, e, i, r, n) {
        var s,
          o,
          a = t.imageData,
          h = !1,
          c = !1,
          l = 0.5 * e,
          u = 0.5 * i,
          f = m.filterBackend.resources,
          d = 0,
          g = 0,
          p = e,
          v = 0;
        for (
          f.sliceByTwo || (f.sliceByTwo = document.createElement('canvas')),
            ((s = f.sliceByTwo).width < 1.5 * e || s.height < i) &&
              ((s.width = 1.5 * e), (s.height = i)),
            (o = s.getContext('2d')).clearRect(0, 0, 1.5 * e, i),
            o.putImageData(a, 0, 0),
            r = A(r),
            n = A(n);
          !h || !c;

        )
          (i = u),
            r < A(0.5 * (e = l)) ? (l = A(0.5 * l)) : ((l = r), (h = !0)),
            n < A(0.5 * u) ? (u = A(0.5 * u)) : ((u = n), (c = !0)),
            o.drawImage(s, d, g, e, i, p, v, l, u),
            (d = p),
            (g = v),
            (v += u);
        return o.getImageData(d, g, r, n);
      },
      lanczosResize: function(t, g, p, v, m) {
        var b = t.imageData.data,
          _ = t.ctx.createImageData(v, m),
          y = _.data,
          x = this.lanczosCreate(this.lanczosLobes),
          C = this.rcpScaleX,
          S = this.rcpScaleY,
          T = 2 / this.rcpScaleX,
          w = 2 / this.rcpScaleY,
          O = I((C * this.lanczosLobes) / 2),
          k = I((S * this.lanczosLobes) / 2),
          D = {},
          E = {},
          P = {};
        return (function t(e) {
          var i, r, n, s, o, a, h, c, l, u, f;
          for (E.x = (e + 0.5) * C, P.x = A(E.x), i = 0; i < m; i++) {
            for (
              E.y = (i + 0.5) * S,
                P.y = A(E.y),
                l = c = h = a = o = 0,
                r = P.x - O;
              r <= P.x + O;
              r++
            )
              if (!(r < 0 || g <= r)) {
                (u = A(1e3 * F(r - E.x))), D[u] || (D[u] = {});
                for (var d = P.y - k; d <= P.y + k; d++)
                  d < 0 ||
                    p <= d ||
                    ((f = A(1e3 * F(d - E.y))),
                    D[u][f] ||
                      (D[u][f] = x(M(j(u * T, 2) + j(f * w, 2)) / 1e3)),
                    0 < (n = D[u][f]) &&
                      ((o += n),
                      (a += n * b[(s = 4 * (d * g + r))]),
                      (h += n * b[s + 1]),
                      (c += n * b[s + 2]),
                      (l += n * b[s + 3])));
              }
            (y[(s = 4 * (i * v + e))] = a / o),
              (y[s + 1] = h / o),
              (y[s + 2] = c / o),
              (y[s + 3] = l / o);
          }
          return ++e < v ? t(e) : _;
        })(0);
      },
      bilinearFiltering: function(t, e, i, r, n) {
        var s,
          o,
          a,
          h,
          c,
          l,
          u,
          f,
          d,
          g = 0,
          p = this.rcpScaleX,
          v = this.rcpScaleY,
          m = 4 * (e - 1),
          b = t.imageData.data,
          _ = t.ctx.createImageData(r, n),
          y = _.data;
        for (a = 0; a < n; a++)
          for (h = 0; h < r; h++)
            for (
              c = p * h - (s = A(p * h)),
                l = v * a - (o = A(v * a)),
                d = 4 * (o * e + s),
                u = 0;
              u < 4;
              u++
            )
              (f =
                b[d + u] * (1 - c) * (1 - l) +
                b[d + 4 + u] * c * (1 - l) +
                b[d + m + u] * l * (1 - c) +
                b[d + m + 4 + u] * c * l),
                (y[g++] = f);
        return _;
      },
      hermiteFastResize: function(t, e, i, r, n) {
        for (
          var s = this.rcpScaleX,
            o = this.rcpScaleY,
            a = I(s / 2),
            h = I(o / 2),
            c = t.imageData.data,
            l = t.ctx.createImageData(r, n),
            u = l.data,
            f = 0;
          f < n;
          f++
        )
          for (var d = 0; d < r; d++) {
            for (
              var g = 4 * (d + f * r),
                p = 0,
                v = 0,
                m = 0,
                b = 0,
                _ = 0,
                y = 0,
                x = 0,
                C = (f + 0.5) * o,
                S = A(f * o);
              S < (f + 1) * o;
              S++
            )
              for (
                var T = F(C - (S + 0.5)) / h,
                  w = (d + 0.5) * s,
                  O = T * T,
                  k = A(d * s);
                k < (d + 1) * s;
                k++
              ) {
                var D = F(w - (k + 0.5)) / a,
                  E = M(O + D * D);
                (1 < E && E < -1) ||
                  (0 < (p = 2 * E * E * E - 3 * E * E + 1) &&
                    ((x += p * c[(D = 4 * (k + S * e)) + 3]),
                    (m += p),
                    c[D + 3] < 255 && (p = (p * c[D + 3]) / 250),
                    (b += p * c[D]),
                    (_ += p * c[D + 1]),
                    (y += p * c[D + 2]),
                    (v += p)));
              }
            (u[g] = b / v),
              (u[g + 1] = _ / v),
              (u[g + 2] = y / v),
              (u[g + 3] = x / m);
          }
        return l;
      },
      toObject: function() {
        return {
          type: this.type,
          scaleX: this.scaleX,
          scaleY: this.scaleY,
          resizeType: this.resizeType,
          lanczosLobes: this.lanczosLobes,
        };
      },
    })),
      (m.Image.filters.Resize.fromObject =
        m.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var e = t.fabric || (t.fabric = {}),
      i = e.Image.filters,
      r = e.util.createClass;
    (i.Contrast = r(i.BaseFilter, {
      type: 'Contrast',
      fragmentSource:
        'precision highp float;\nuniform sampler2D uTexture;\nuniform float uContrast;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\ncolor.rgb = contrastF * (color.rgb - 0.5) + 0.5;\ngl_FragColor = color;\n}',
      contrast: 0,
      mainParameter: 'contrast',
      applyTo2d: function(t) {
        if (0 !== this.contrast) {
          var e,
            i = t.imageData.data,
            r = i.length,
            n = Math.floor(255 * this.contrast),
            s = (259 * (n + 255)) / (255 * (259 - n));
          for (e = 0; e < r; e += 4)
            (i[e] = s * (i[e] - 128) + 128),
              (i[e + 1] = s * (i[e + 1] - 128) + 128),
              (i[e + 2] = s * (i[e + 2] - 128) + 128);
        }
      },
      getUniformLocations: function(t, e) {
        return { uContrast: t.getUniformLocation(e, 'uContrast') };
      },
      sendUniformData: function(t, e) {
        t.uniform1f(e.uContrast, this.contrast);
      },
    })),
      (e.Image.filters.Contrast.fromObject =
        e.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var e = t.fabric || (t.fabric = {}),
      i = e.Image.filters,
      r = e.util.createClass;
    (i.Saturation = r(i.BaseFilter, {
      type: 'Saturation',
      fragmentSource:
        'precision highp float;\nuniform sampler2D uTexture;\nuniform float uSaturation;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nfloat rgMax = max(color.r, color.g);\nfloat rgbMax = max(rgMax, color.b);\ncolor.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\ncolor.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\ncolor.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\ngl_FragColor = color;\n}',
      saturation: 0,
      mainParameter: 'saturation',
      applyTo2d: function(t) {
        if (0 !== this.saturation) {
          var e,
            i,
            r = t.imageData.data,
            n = r.length,
            s = -this.saturation;
          for (e = 0; e < n; e += 4)
            (i = Math.max(r[e], r[e + 1], r[e + 2])),
              (r[e] += i !== r[e] ? (i - r[e]) * s : 0),
              (r[e + 1] += i !== r[e + 1] ? (i - r[e + 1]) * s : 0),
              (r[e + 2] += i !== r[e + 2] ? (i - r[e + 2]) * s : 0);
        }
      },
      getUniformLocations: function(t, e) {
        return { uSaturation: t.getUniformLocation(e, 'uSaturation') };
      },
      sendUniformData: function(t, e) {
        t.uniform1f(e.uSaturation, -this.saturation);
      },
    })),
      (e.Image.filters.Saturation.fromObject =
        e.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var g = t.fabric || (t.fabric = {}),
      e = g.Image.filters,
      i = g.util.createClass;
    (e.Blur = i(e.BaseFilter, {
      type: 'Blur',
      fragmentSource:
        'precision highp float;\nuniform sampler2D uTexture;\nuniform vec2 uDelta;\nvarying vec2 vTexCoord;\nconst float nSamples = 15.0;\nvec3 v3offset = vec3(12.9898, 78.233, 151.7182);\nfloat random(vec3 scale) {\nreturn fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n}\nvoid main() {\nvec4 color = vec4(0.0);\nfloat total = 0.0;\nfloat offset = random(v3offset);\nfor (float t = -nSamples; t <= nSamples; t++) {\nfloat percent = (t + offset - 0.5) / nSamples;\nfloat weight = 1.0 - abs(percent);\ncolor += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\ntotal += weight;\n}\ngl_FragColor = color / total;\n}',
      blur: 0,
      mainParameter: 'blur',
      applyTo: function(t) {
        t.webgl
          ? ((this.aspectRatio = t.sourceWidth / t.sourceHeight),
            t.passes++,
            this._setupFrameBuffer(t),
            (this.horizontal = !0),
            this.applyToWebGL(t),
            this._swapTextures(t),
            this._setupFrameBuffer(t),
            (this.horizontal = !1),
            this.applyToWebGL(t),
            this._swapTextures(t))
          : this.applyTo2d(t);
      },
      applyTo2d: function(t) {
        t.imageData = this.simpleBlur(t);
      },
      simpleBlur: function(t) {
        var e,
          i,
          r = t.filterBackend.resources,
          n = t.imageData.width,
          s = t.imageData.height;
        r.blurLayer1 ||
          ((r.blurLayer1 = g.util.createCanvasElement()),
          (r.blurLayer2 = g.util.createCanvasElement())),
          (e = r.blurLayer1),
          (i = r.blurLayer2),
          (e.width === n && e.height === s) ||
            ((i.width = e.width = n), (i.height = e.height = s));
        var o,
          a,
          h,
          c,
          l = e.getContext('2d'),
          u = i.getContext('2d'),
          f = 0.06 * this.blur * 0.5;
        for (
          l.putImageData(t.imageData, 0, 0), u.clearRect(0, 0, n, s), c = -15;
          c <= 15;
          c++
        )
          (h = f * (a = c / 15) * n + (o = (Math.random() - 0.5) / 4)),
            (u.globalAlpha = 1 - Math.abs(a)),
            u.drawImage(e, h, o),
            l.drawImage(i, 0, 0),
            (u.globalAlpha = 1),
            u.clearRect(0, 0, i.width, i.height);
        for (c = -15; c <= 15; c++)
          (h = f * (a = c / 15) * s + (o = (Math.random() - 0.5) / 4)),
            (u.globalAlpha = 1 - Math.abs(a)),
            u.drawImage(e, o, h),
            l.drawImage(i, 0, 0),
            (u.globalAlpha = 1),
            u.clearRect(0, 0, i.width, i.height);
        t.ctx.drawImage(e, 0, 0);
        var d = t.ctx.getImageData(0, 0, e.width, e.height);
        return (l.globalAlpha = 1), l.clearRect(0, 0, e.width, e.height), d;
      },
      getUniformLocations: function(t, e) {
        return { delta: t.getUniformLocation(e, 'uDelta') };
      },
      sendUniformData: function(t, e) {
        var i = this.chooseRightDelta();
        t.uniform2fv(e.delta, i);
      },
      chooseRightDelta: function() {
        var t,
          e = 1,
          i = [0, 0];
        return (
          this.horizontal
            ? 1 < this.aspectRatio && (e = 1 / this.aspectRatio)
            : this.aspectRatio < 1 && (e = this.aspectRatio),
          (t = e * this.blur * 0.12),
          this.horizontal ? (i[0] = t) : (i[1] = t),
          i
        );
      },
    })),
      (e.Blur.fromObject = g.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var e = t.fabric || (t.fabric = {}),
      i = e.Image.filters,
      r = e.util.createClass;
    (i.Gamma = r(i.BaseFilter, {
      type: 'Gamma',
      fragmentSource:
        'precision highp float;\nuniform sampler2D uTexture;\nuniform vec3 uGamma;\nvarying vec2 vTexCoord;\nvoid main() {\nvec4 color = texture2D(uTexture, vTexCoord);\nvec3 correction = (1.0 / uGamma);\ncolor.r = pow(color.r, correction.r);\ncolor.g = pow(color.g, correction.g);\ncolor.b = pow(color.b, correction.b);\ngl_FragColor = color;\ngl_FragColor.rgb *= color.a;\n}',
      gamma: [1, 1, 1],
      mainParameter: 'gamma',
      initialize: function(t) {
        (this.gamma = [1, 1, 1]),
          i.BaseFilter.prototype.initialize.call(this, t);
      },
      applyTo2d: function(t) {
        var e,
          i = t.imageData.data,
          r = this.gamma,
          n = i.length,
          s = 1 / r[0],
          o = 1 / r[1],
          a = 1 / r[2];
        for (
          this.rVals ||
            ((this.rVals = new Uint8Array(256)),
            (this.gVals = new Uint8Array(256)),
            (this.bVals = new Uint8Array(256))),
            e = 0,
            n = 256;
          e < n;
          e++
        )
          (this.rVals[e] = 255 * Math.pow(e / 255, s)),
            (this.gVals[e] = 255 * Math.pow(e / 255, o)),
            (this.bVals[e] = 255 * Math.pow(e / 255, a));
        for (e = 0, n = i.length; e < n; e += 4)
          (i[e] = this.rVals[i[e]]),
            (i[e + 1] = this.gVals[i[e + 1]]),
            (i[e + 2] = this.bVals[i[e + 2]]);
      },
      getUniformLocations: function(t, e) {
        return { uGamma: t.getUniformLocation(e, 'uGamma') };
      },
      sendUniformData: function(t, e) {
        t.uniform3fv(e.uGamma, this.gamma);
      },
    })),
      (e.Image.filters.Gamma.fromObject =
        e.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var n = t.fabric || (t.fabric = {}),
      e = n.Image.filters,
      i = n.util.createClass;
    (e.Composed = i(e.BaseFilter, {
      type: 'Composed',
      subFilters: [],
      initialize: function(t) {
        this.callSuper('initialize', t),
          (this.subFilters = this.subFilters.slice(0));
      },
      applyTo: function(e) {
        (e.passes += this.subFilters.length - 1),
          this.subFilters.forEach(function(t) {
            t.applyTo(e);
          });
      },
      toObject: function() {
        return n.util.object.extend(this.callSuper('toObject'), {
          subFilters: this.subFilters.map(function(t) {
            return t.toObject();
          }),
        });
      },
      isNeutralState: function() {
        return !this.subFilters.some(function(t) {
          return !t.isNeutralState();
        });
      },
    })),
      (n.Image.filters.Composed.fromObject = function(t, e) {
        var i = (t.subFilters || []).map(function(t) {
            return new n.Image.filters[t.type](t);
          }),
          r = new n.Image.filters.Composed({ subFilters: i });
        return e && e(r), r;
      });
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var s = t.fabric || (t.fabric = {}),
      e = s.Image.filters,
      i = s.util.createClass;
    (e.HueRotation = i(e.ColorMatrix, {
      type: 'HueRotation',
      rotation: 0,
      mainParameter: 'rotation',
      calculateMatrix: function() {
        var t = this.rotation * Math.PI,
          e = s.util.cos(t),
          i = s.util.sin(t),
          r = Math.sqrt(1 / 3) * i,
          n = 1 - e;
        (this.matrix = [
          1,
          0,
          0,
          0,
          0,
          0,
          1,
          0,
          0,
          0,
          0,
          0,
          1,
          0,
          0,
          0,
          0,
          0,
          1,
          0,
        ]),
          (this.matrix[0] = e + n / 3),
          (this.matrix[1] = (1 / 3) * n - r),
          (this.matrix[2] = (1 / 3) * n + r),
          (this.matrix[5] = (1 / 3) * n + r),
          (this.matrix[6] = e + (1 / 3) * n),
          (this.matrix[7] = (1 / 3) * n - r),
          (this.matrix[10] = (1 / 3) * n - r),
          (this.matrix[11] = (1 / 3) * n + r),
          (this.matrix[12] = e + (1 / 3) * n);
      },
      isNeutralState: function(t) {
        return (
          this.calculateMatrix(),
          e.BaseFilter.prototype.isNeutralState.call(this, t)
        );
      },
      applyTo: function(t) {
        this.calculateMatrix(), e.BaseFilter.prototype.applyTo.call(this, t);
      },
    })),
      (s.Image.filters.HueRotation.fromObject =
        s.Image.filters.BaseFilter.fromObject);
  })('undefined' != typeof exports ? exports : this),
  (function(t) {
    'use strict';
    var d = t.fabric || (t.fabric = {}),
      g = d.util.object.clone;
    d.Text
      ? d.warn('fabric.Text is already defined')
      : ((d.Text = d.util.createClass(d.Object, {
          _dimensionAffectingProps: [
            'fontSize',
            'fontWeight',
            'fontFamily',
            'fontStyle',
            'lineHeight',
            'text',
            'charSpacing',
            'textAlign',
            'styles',
          ],
          _reNewline: /\r?\n/,
          _reSpacesAndTabs: /[ \t\r]/g,
          _reSpaceAndTab: /[ \t\r]/,
          _reWords: /\S+/g,
          type: 'text',
          fontSize: 40,
          fontWeight: 'normal',
          fontFamily: 'Times New Roman',
          underline: !1,
          overline: !1,
          linethrough: !1,
          textAlign: 'left',
          fontStyle: 'normal',
          lineHeight: 1.16,
          superscript: { size: 0.6, baseline: -0.35 },
          subscript: { size: 0.6, baseline: 0.11 },
          textBackgroundColor: '',
          stateProperties: d.Object.prototype.stateProperties.concat(
            'fontFamily',
            'fontWeight',
            'fontSize',
            'text',
            'underline',
            'overline',
            'linethrough',
            'textAlign',
            'fontStyle',
            'lineHeight',
            'textBackgroundColor',
            'charSpacing',
            'styles'
          ),
          cacheProperties: d.Object.prototype.cacheProperties.concat(
            'fontFamily',
            'fontWeight',
            'fontSize',
            'text',
            'underline',
            'overline',
            'linethrough',
            'textAlign',
            'fontStyle',
            'lineHeight',
            'textBackgroundColor',
            'charSpacing',
            'styles'
          ),
          stroke: null,
          shadow: null,
          _fontSizeFraction: 0.222,
          offsets: { underline: 0.1, linethrough: -0.315, overline: -0.88 },
          _fontSizeMult: 1.13,
          charSpacing: 0,
          styles: null,
          _measuringContext: null,
          deltaY: 0,
          _styleProperties: [
            'stroke',
            'strokeWidth',
            'fill',
            'fontFamily',
            'fontSize',
            'fontWeight',
            'fontStyle',
            'underline',
            'overline',
            'linethrough',
            'deltaY',
            'textBackgroundColor',
          ],
          __charBounds: [],
          CACHE_FONT_SIZE: 400,
          MIN_TEXT_WIDTH: 2,
          initialize: function(t, e) {
            (this.styles = (e && e.styles) || {}),
              (this.text = t),
              (this.__skipDimension = !0),
              this.callSuper('initialize', e),
              (this.__skipDimension = !1),
              this.initDimensions(),
              this.setCoords(),
              this.setupState({ propertySet: '_dimensionAffectingProps' });
          },
          getMeasuringContext: function() {
            return (
              d._measuringContext ||
                (d._measuringContext =
                  (this.canvas && this.canvas.contextCache) ||
                  d.util.createCanvasElement().getContext('2d')),
              d._measuringContext
            );
          },
          _splitText: function() {
            var t = this._splitTextIntoLines(this.text);
            return (
              (this.textLines = t.lines),
              (this._textLines = t.graphemeLines),
              (this._unwrappedTextLines = t._unwrappedLines),
              (this._text = t.graphemeText),
              t
            );
          },
          initDimensions: function() {
            this.__skipDimension ||
              (this._splitText(),
              this._clearCache(),
              (this.width =
                this.calcTextWidth() ||
                this.cursorWidth ||
                this.MIN_TEXT_WIDTH),
              -1 !== this.textAlign.indexOf('justify') && this.enlargeSpaces(),
              (this.height = this.calcTextHeight()),
              this.saveState({ propertySet: '_dimensionAffectingProps' }));
          },
          enlargeSpaces: function() {
            for (
              var t, e, i, r, n, s, o, a = 0, h = this._textLines.length;
              a < h;
              a++
            )
              if (
                ('justify' === this.textAlign ||
                  (a !== h - 1 && !this.isEndOfWrapping(a))) &&
                ((r = 0),
                (n = this._textLines[a]),
                (e = this.getLineWidth(a)) < this.width &&
                  (o = this.textLines[a].match(this._reSpacesAndTabs)))
              ) {
                (i = o.length), (t = (this.width - e) / i);
                for (var c = 0, l = n.length; c <= l; c++)
                  (s = this.__charBounds[a][c]),
                    this._reSpaceAndTab.test(n[c])
                      ? ((s.width += t),
                        (s.kernedWidth += t),
                        (s.left += r),
                        (r += t))
                      : (s.left += r);
              }
          },
          isEndOfWrapping: function(t) {
            return t === this._textLines.length - 1;
          },
          toString: function() {
            return (
              '#<fabric.Text (' +
              this.complexity() +
              '): { "text": "' +
              this.text +
              '", "fontFamily": "' +
              this.fontFamily +
              '" }>'
            );
          },
          _getCacheCanvasDimensions: function() {
            var t = this.callSuper('_getCacheCanvasDimensions'),
              e = this.fontSize;
            return (t.width += e * t.zoomX), (t.height += e * t.zoomY), t;
          },
          _render: function(t) {
            this._setTextStyles(t),
              this._renderTextLinesBackground(t),
              this._renderTextDecoration(t, 'underline'),
              this._renderText(t),
              this._renderTextDecoration(t, 'overline'),
              this._renderTextDecoration(t, 'linethrough');
          },
          _renderText: function(t) {
            'stroke' === this.paintFirst
              ? (this._renderTextStroke(t), this._renderTextFill(t))
              : (this._renderTextFill(t), this._renderTextStroke(t));
          },
          _setTextStyles: function(t, e, i) {
            (t.textBaseline = 'alphabetic'),
              (t.font = this._getFontDeclaration(e, i));
          },
          calcTextWidth: function() {
            for (
              var t = this.getLineWidth(0), e = 1, i = this._textLines.length;
              e < i;
              e++
            ) {
              var r = this.getLineWidth(e);
              t < r && (t = r);
            }
            return t;
          },
          _renderTextLine: function(t, e, i, r, n, s) {
            this._renderChars(t, e, i, r, n, s);
          },
          _renderTextLinesBackground: function(t) {
            if (
              this.textBackgroundColor ||
              this.styleHas('textBackgroundColor')
            ) {
              for (
                var e,
                  i,
                  r,
                  n,
                  s,
                  o,
                  a = 0,
                  h = t.fillStyle,
                  c = this._getLeftOffset(),
                  l = this._getTopOffset(),
                  u = 0,
                  f = 0,
                  d = 0,
                  g = this._textLines.length;
                d < g;
                d++
              )
                if (
                  ((e = this.getHeightOfLine(d)),
                  this.textBackgroundColor ||
                    this.styleHas('textBackgroundColor', d))
                ) {
                  (r = this._textLines[d]),
                    (i = this._getLineLeftOffset(d)),
                    (u = f = 0),
                    (n = this.getValueOfPropertyAt(
                      d,
                      0,
                      'textBackgroundColor'
                    ));
                  for (var p = 0, v = r.length; p < v; p++)
                    (s = this.__charBounds[d][p]),
                      (o = this.getValueOfPropertyAt(
                        d,
                        p,
                        'textBackgroundColor'
                      )) !== n
                        ? ((t.fillStyle = n) &&
                            t.fillRect(
                              c + i + u,
                              l + a,
                              f,
                              e / this.lineHeight
                            ),
                          (u = s.left),
                          (f = s.width),
                          (n = o))
                        : (f += s.kernedWidth);
                  o &&
                    ((t.fillStyle = o),
                    t.fillRect(c + i + u, l + a, f, e / this.lineHeight)),
                    (a += e);
                } else a += e;
              (t.fillStyle = h), this._removeShadow(t);
            }
          },
          getFontCache: function(t) {
            var e = t.fontFamily.toLowerCase();
            d.charWidthsCache[e] || (d.charWidthsCache[e] = {});
            var i = d.charWidthsCache[e],
              r =
                t.fontStyle.toLowerCase() +
                '_' +
                (t.fontWeight + '').toLowerCase();
            return i[r] || (i[r] = {}), i[r];
          },
          _applyCharStyles: function(t, e, i, r, n) {
            this._setFillStyles(e, n),
              this._setStrokeStyles(e, n),
              (e.font = this._getFontDeclaration(n));
          },
          _measureChar: function(t, e, i, r) {
            var n,
              s,
              o,
              a,
              h = this.getFontCache(e),
              c = i + t,
              l = this._getFontDeclaration(e) === this._getFontDeclaration(r),
              u = e.fontSize / this.CACHE_FONT_SIZE;
            if (
              (i && void 0 !== h[i] && (o = h[i]),
              void 0 !== h[t] && (a = n = h[t]),
              l && void 0 !== h[c] && (a = (s = h[c]) - o),
              void 0 === n || void 0 === o || void 0 === s)
            ) {
              var f = this.getMeasuringContext();
              this._setTextStyles(f, e, !0);
            }
            return (
              void 0 === n && ((a = n = f.measureText(t).width), (h[t] = n)),
              void 0 === o &&
                l &&
                i &&
                ((o = f.measureText(i).width), (h[i] = o)),
              l &&
                void 0 === s &&
                ((s = f.measureText(c).width), (a = (h[c] = s) - o)),
              { width: n * u, kernedWidth: a * u }
            );
          },
          getHeightOfChar: function(t, e) {
            return this.getValueOfPropertyAt(t, e, 'fontSize');
          },
          measureLine: function(t) {
            var e = this._measureLine(t);
            return (
              0 !== this.charSpacing &&
                (e.width -= this._getWidthOfCharSpacing()),
              e.width < 0 && (e.width = 0),
              e
            );
          },
          _measureLine: function(t) {
            var e,
              i,
              r,
              n,
              s = 0,
              o = this._textLines[t],
              a = new Array(o.length);
            for (this.__charBounds[t] = a, e = 0; e < o.length; e++)
              (i = o[e]),
                (n = this._getGraphemeBox(i, t, e, r)),
                (s += (a[e] = n).kernedWidth),
                (r = i);
            return (
              (a[e] = {
                left: n ? n.left + n.width : 0,
                width: 0,
                kernedWidth: 0,
                height: this.fontSize,
              }),
              { width: s, numOfSpaces: 0 }
            );
          },
          _getGraphemeBox: function(t, e, i, r, n) {
            var s,
              o = this.getCompleteStyleDeclaration(e, i),
              a = r ? this.getCompleteStyleDeclaration(e, i - 1) : {},
              h = this._measureChar(t, o, r, a),
              c = h.kernedWidth,
              l = h.width;
            0 !== this.charSpacing &&
              ((l += s = this._getWidthOfCharSpacing()), (c += s));
            var u = {
              width: l,
              left: 0,
              height: o.fontSize,
              kernedWidth: c,
              deltaY: o.deltaY,
            };
            if (0 < i && !n) {
              var f = this.__charBounds[e][i - 1];
              u.left = f.left + f.width + h.kernedWidth - h.width;
            }
            return u;
          },
          getHeightOfLine: function(t) {
            if (this.__lineHeights[t]) return this.__lineHeights[t];
            for (
              var e = this._textLines[t],
                i = this.getHeightOfChar(t, 0),
                r = 1,
                n = e.length;
              r < n;
              r++
            )
              i = Math.max(this.getHeightOfChar(t, r), i);
            return (this.__lineHeights[t] =
              i * this.lineHeight * this._fontSizeMult);
          },
          calcTextHeight: function() {
            for (var t, e = 0, i = 0, r = this._textLines.length; i < r; i++)
              (t = this.getHeightOfLine(i)),
                (e += i === r - 1 ? t / this.lineHeight : t);
            return e;
          },
          _getLeftOffset: function() {
            return -this.width / 2;
          },
          _getTopOffset: function() {
            return -this.height / 2;
          },
          _renderTextCommon: function(t, e) {
            t.save();
            for (
              var i = 0,
                r = this._getLeftOffset(),
                n = this._getTopOffset(),
                s = this._applyPatternGradientTransform(
                  t,
                  'fillText' === e ? this.fill : this.stroke
                ),
                o = 0,
                a = this._textLines.length;
              o < a;
              o++
            ) {
              var h = this.getHeightOfLine(o),
                c = h / this.lineHeight,
                l = this._getLineLeftOffset(o);
              this._renderTextLine(
                e,
                t,
                this._textLines[o],
                r + l - s.offsetX,
                n + i + c - s.offsetY,
                o
              ),
                (i += h);
            }
            t.restore();
          },
          _renderTextFill: function(t) {
            (this.fill || this.styleHas('fill')) &&
              this._renderTextCommon(t, 'fillText');
          },
          _renderTextStroke: function(t) {
            ((this.stroke && 0 !== this.strokeWidth) ||
              !this.isEmptyStyles()) &&
              (this.shadow &&
                !this.shadow.affectStroke &&
                this._removeShadow(t),
              t.save(),
              this._setLineDash(t, this.strokeDashArray),
              t.beginPath(),
              this._renderTextCommon(t, 'strokeText'),
              t.closePath(),
              t.restore());
          },
          _renderChars: function(t, e, i, r, n, s) {
            var o,
              a,
              h,
              c,
              l = this.getHeightOfLine(s),
              u = -1 !== this.textAlign.indexOf('justify'),
              f = '',
              d = 0,
              g = !u && 0 === this.charSpacing && this.isEmptyStyles(s);
            if (
              (e.save(),
              (n -= (l * this._fontSizeFraction) / this.lineHeight),
              g)
            )
              return (
                this._renderChar(t, e, s, 0, this.textLines[s], r, n, l),
                void e.restore()
              );
            for (var p = 0, v = i.length - 1; p <= v; p++)
              (c = p === v || this.charSpacing),
                (f += i[p]),
                (h = this.__charBounds[s][p]),
                0 === d
                  ? ((r += h.kernedWidth - h.width), (d += h.width))
                  : (d += h.kernedWidth),
                u && !c && this._reSpaceAndTab.test(i[p]) && (c = !0),
                c ||
                  ((o = o || this.getCompleteStyleDeclaration(s, p)),
                  (a = this.getCompleteStyleDeclaration(s, p + 1)),
                  (c = this._hasStyleChanged(o, a))),
                c &&
                  (this._renderChar(t, e, s, p, f, r, n, l),
                  (f = ''),
                  (o = a),
                  (r += d),
                  (d = 0));
            e.restore();
          },
          _renderChar: function(t, e, i, r, n, s, o) {
            var a = this._getStyleDeclaration(i, r),
              h = this.getCompleteStyleDeclaration(i, r),
              c = 'fillText' === t && h.fill,
              l = 'strokeText' === t && h.stroke && h.strokeWidth;
            (l || c) &&
              (a && e.save(),
              this._applyCharStyles(t, e, i, r, h),
              a && a.textBackgroundColor && this._removeShadow(e),
              a && a.deltaY && (o += a.deltaY),
              c && e.fillText(n, s, o),
              l && e.strokeText(n, s, o),
              a && e.restore());
          },
          setSuperscript: function(t, e) {
            return this._setScript(t, e, this.superscript);
          },
          setSubscript: function(t, e) {
            return this._setScript(t, e, this.subscript);
          },
          _setScript: function(t, e, i) {
            var r = this.get2DCursorLocation(t, !0),
              n = this.getValueOfPropertyAt(
                r.lineIndex,
                r.charIndex,
                'fontSize'
              ),
              s = this.getValueOfPropertyAt(r.lineIndex, r.charIndex, 'deltaY'),
              o = { fontSize: n * i.size, deltaY: s + n * i.baseline };
            return this.setSelectionStyles(o, t, e), this;
          },
          _hasStyleChanged: function(t, e) {
            return (
              t.fill !== e.fill ||
              t.stroke !== e.stroke ||
              t.strokeWidth !== e.strokeWidth ||
              t.fontSize !== e.fontSize ||
              t.fontFamily !== e.fontFamily ||
              t.fontWeight !== e.fontWeight ||
              t.fontStyle !== e.fontStyle ||
              t.deltaY !== e.deltaY
            );
          },
          _hasStyleChangedForSvg: function(t, e) {
            return (
              this._hasStyleChanged(t, e) ||
              t.overline !== e.overline ||
              t.underline !== e.underline ||
              t.linethrough !== e.linethrough
            );
          },
          _getLineLeftOffset: function(t) {
            var e = this.getLineWidth(t);
            return 'center' === this.textAlign
              ? (this.width - e) / 2
              : 'right' === this.textAlign
              ? this.width - e
              : 'justify-center' === this.textAlign && this.isEndOfWrapping(t)
              ? (this.width - e) / 2
              : 'justify-right' === this.textAlign && this.isEndOfWrapping(t)
              ? this.width - e
              : 0;
          },
          _clearCache: function() {
            (this.__lineWidths = []),
              (this.__lineHeights = []),
              (this.__charBounds = []);
          },
          _shouldClearDimensionCache: function() {
            var t = this._forceClearCache;
            return (
              t || (t = this.hasStateChanged('_dimensionAffectingProps')),
              t && ((this.dirty = !0), (this._forceClearCache = !1)),
              t
            );
          },
          getLineWidth: function(t) {
            return this.__lineWidths[t]
              ? this.__lineWidths[t]
              : ((e =
                  '' === this._textLines[t] ? 0 : this.measureLine(t).width),
                (this.__lineWidths[t] = e));
            var e;
          },
          _getWidthOfCharSpacing: function() {
            return 0 !== this.charSpacing
              ? (this.fontSize * this.charSpacing) / 1e3
              : 0;
          },
          getValueOfPropertyAt: function(t, e, i) {
            var r = this._getStyleDeclaration(t, e);
            return r && void 0 !== r[i] ? r[i] : this[i];
          },
          _renderTextDecoration: function(t, e) {
            if (this[e] || this.styleHas(e)) {
              for (
                var i,
                  r,
                  n,
                  s,
                  o,
                  a,
                  h,
                  c,
                  l,
                  u,
                  f,
                  d,
                  g,
                  p,
                  v,
                  m,
                  b = this._getLeftOffset(),
                  _ = this._getTopOffset(),
                  y = this._getWidthOfCharSpacing(),
                  x = 0,
                  C = this._textLines.length;
                x < C;
                x++
              )
                if (
                  ((i = this.getHeightOfLine(x)),
                  this[e] || this.styleHas(e, x))
                ) {
                  (h = this._textLines[x]),
                    (p = i / this.lineHeight),
                    (s = this._getLineLeftOffset(x)),
                    (f = u = 0),
                    (c = this.getValueOfPropertyAt(x, 0, e)),
                    (m = this.getValueOfPropertyAt(x, 0, 'fill')),
                    (l = _ + p * (1 - this._fontSizeFraction)),
                    (r = this.getHeightOfChar(x, 0)),
                    (o = this.getValueOfPropertyAt(x, 0, 'deltaY'));
                  for (var S = 0, T = h.length; S < T; S++)
                    (d = this.__charBounds[x][S]),
                      (g = this.getValueOfPropertyAt(x, S, e)),
                      (v = this.getValueOfPropertyAt(x, S, 'fill')),
                      (n = this.getHeightOfChar(x, S)),
                      (a = this.getValueOfPropertyAt(x, S, 'deltaY')),
                      (g !== c || v !== m || n !== r || a !== o) && 0 < f
                        ? ((t.fillStyle = m),
                          c &&
                            m &&
                            t.fillRect(
                              b + s + u,
                              l + this.offsets[e] * r + o,
                              f,
                              this.fontSize / 15
                            ),
                          (u = d.left),
                          (f = d.width),
                          (c = g),
                          (m = v),
                          (r = n),
                          (o = a))
                        : (f += d.kernedWidth);
                  (t.fillStyle = v),
                    g &&
                      v &&
                      t.fillRect(
                        b + s + u,
                        l + this.offsets[e] * r + o,
                        f - y,
                        this.fontSize / 15
                      ),
                    (_ += i);
                } else _ += i;
              this._removeShadow(t);
            }
          },
          _getFontDeclaration: function(t, e) {
            var i = t || this,
              r = this.fontFamily,
              n = -1 < d.Text.genericFonts.indexOf(r.toLowerCase()),
              s =
                void 0 === r || -1 < r.indexOf("'") || -1 < r.indexOf('"') || n
                  ? i.fontFamily
                  : '"' + i.fontFamily + '"';
            return [
              d.isLikelyNode ? i.fontWeight : i.fontStyle,
              d.isLikelyNode ? i.fontStyle : i.fontWeight,
              e ? this.CACHE_FONT_SIZE + 'px' : i.fontSize + 'px',
              s,
            ].join(' ');
          },
          render: function(t) {
            this.visible &&
              ((this.canvas &&
                this.canvas.skipOffscreen &&
                !this.group &&
                !this.isOnScreen()) ||
                (this._shouldClearDimensionCache() && this.initDimensions(),
                this.callSuper('render', t)));
          },
          _splitTextIntoLines: function(t) {
            for (
              var e = t.split(this._reNewline),
                i = new Array(e.length),
                r = ['\n'],
                n = [],
                s = 0;
              s < e.length;
              s++
            )
              (i[s] = d.util.string.graphemeSplit(e[s])),
                (n = n.concat(i[s], r));
            return (
              n.pop(),
              {
                _unwrappedLines: i,
                lines: e,
                graphemeText: n,
                graphemeLines: i,
              }
            );
          },
          toObject: function(t) {
            var e = [
                'text',
                'fontSize',
                'fontWeight',
                'fontFamily',
                'fontStyle',
                'lineHeight',
                'underline',
                'overline',
                'linethrough',
                'textAlign',
                'textBackgroundColor',
                'charSpacing',
              ].concat(t),
              i = this.callSuper('toObject', e);
            return (i.styles = g(this.styles, !0)), i;
          },
          set: function(t, e) {
            this.callSuper('set', t, e);
            var i = !1;
            if ('object' == typeof t)
              for (var r in t)
                i = i || -1 !== this._dimensionAffectingProps.indexOf(r);
            else i = -1 !== this._dimensionAffectingProps.indexOf(t);
            return i && (this.initDimensions(), this.setCoords()), this;
          },
          complexity: function() {
            return 1;
          },
        })),
        (d.Text.ATTRIBUTE_NAMES = d.SHARED_ATTRIBUTES.concat(
          'x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor'.split(
            ' '
          )
        )),
        (d.Text.DEFAULT_SVG_FONT_SIZE = 16),
        (d.Text.fromElement = function(t, e, i) {
          if (!t) return e(null);
          var r = d.parseAttributes(t, d.Text.ATTRIBUTE_NAMES),
            n = r.textAnchor || 'left';
          if (
            (((i = d.util.object.extend(i ? g(i) : {}, r)).top = i.top || 0),
            (i.left = i.left || 0),
            r.textDecoration)
          ) {
            var s = r.textDecoration;
            -1 !== s.indexOf('underline') && (i.underline = !0),
              -1 !== s.indexOf('overline') && (i.overline = !0),
              -1 !== s.indexOf('line-through') && (i.linethrough = !0),
              delete i.textDecoration;
          }
          'dx' in r && (i.left += r.dx),
            'dy' in r && (i.top += r.dy),
            'fontSize' in i || (i.fontSize = d.Text.DEFAULT_SVG_FONT_SIZE);
          var o = '';
          'textContent' in t
            ? (o = t.textContent)
            : 'firstChild' in t &&
              null !== t.firstChild &&
              'data' in t.firstChild &&
              null !== t.firstChild.data &&
              (o = t.firstChild.data),
            (o = o.replace(/^\s+|\s+$|\n+/g, '').replace(/\s+/g, ' '));
          var a = i.strokeWidth;
          i.strokeWidth = 0;
          var h = new d.Text(o, i),
            c = h.getScaledHeight() / h.height,
            l = ((h.height + h.strokeWidth) * h.lineHeight - h.height) * c,
            u = h.getScaledHeight() + l,
            f = 0;
          'center' === n && (f = h.getScaledWidth() / 2),
            'right' === n && (f = h.getScaledWidth()),
            h.set({
              left: h.left - f,
              top:
                h.top -
                (u - h.fontSize * (0.07 + h._fontSizeFraction)) / h.lineHeight,
              strokeWidth: void 0 !== a ? a : 1,
            }),
            e(h);
        }),
        (d.Text.fromObject = function(t, e) {
          return d.Object._fromObject('Text', t, e, 'text');
        }),
        (d.Text.genericFonts = [
          'sans-serif',
          'serif',
          'cursive',
          'fantasy',
          'monospace',
        ]),
        d.util.createAccessors && d.util.createAccessors(d.Text));
  })('undefined' != typeof exports ? exports : this),
  fabric.util.object.extend(fabric.Text.prototype, {
    isEmptyStyles: function(t) {
      if (!this.styles) return !0;
      if (void 0 !== t && !this.styles[t]) return !0;
      var e = void 0 === t ? this.styles : { line: this.styles[t] };
      for (var i in e) for (var r in e[i]) for (var n in e[i][r]) return !1;
      return !0;
    },
    styleHas: function(t, e) {
      if (!this.styles || !t || '' === t) return !1;
      if (void 0 !== e && !this.styles[e]) return !1;
      var i = void 0 === e ? this.styles : { line: this.styles[e] };
      for (var r in i) for (var n in i[r]) if (void 0 !== i[r][n][t]) return !0;
      return !1;
    },
    cleanStyle: function(t) {
      if (!this.styles || !t || '' === t) return !1;
      var e,
        i,
        r = this.styles,
        n = 0,
        s = !0,
        o = 0;
      for (var a in r) {
        for (var h in ((e = 0), r[a])) {
          var c;
          n++,
            (c = r[a][h]).hasOwnProperty(t)
              ? (i ? c[t] !== i && (s = !1) : (i = c[t]),
                c[t] === this[t] && delete c[t])
              : (s = !1),
            0 !== Object.keys(c).length ? e++ : delete r[a][h];
        }
        0 === e && delete r[a];
      }
      for (var l = 0; l < this._textLines.length; l++)
        o += this._textLines[l].length;
      s && n === o && ((this[t] = i), this.removeStyle(t));
    },
    removeStyle: function(t) {
      if (this.styles && t && '' !== t) {
        var e,
          i,
          r,
          n = this.styles;
        for (i in n) {
          for (r in (e = n[i]))
            delete e[r][t], 0 === Object.keys(e[r]).length && delete e[r];
          0 === Object.keys(e).length && delete n[i];
        }
      }
    },
    _extendStyles: function(t, e) {
      var i = this.get2DCursorLocation(t);
      this._getLineStyle(i.lineIndex) || this._setLineStyle(i.lineIndex, {}),
        this._getStyleDeclaration(i.lineIndex, i.charIndex) ||
          this._setStyleDeclaration(i.lineIndex, i.charIndex, {}),
        fabric.util.object.extend(
          this._getStyleDeclaration(i.lineIndex, i.charIndex),
          e
        );
    },
    get2DCursorLocation: function(t, e) {
      void 0 === t && (t = this.selectionStart);
      for (
        var i = e ? this._unwrappedTextLines : this._textLines,
          r = i.length,
          n = 0;
        n < r;
        n++
      ) {
        if (t <= i[n].length) return { lineIndex: n, charIndex: t };
        t -= i[n].length + 1;
      }
      return {
        lineIndex: n - 1,
        charIndex: i[n - 1].length < t ? i[n - 1].length : t,
      };
    },
    getSelectionStyles: function(t, e, i) {
      void 0 === t && (t = this.selectionStart || 0),
        void 0 === e && (e = this.selectionEnd || t);
      for (var r = [], n = t; n < e; n++) r.push(this.getStyleAtPosition(n, i));
      return r;
    },
    getStyleAtPosition: function(t, e) {
      var i = this.get2DCursorLocation(t);
      return (
        (e
          ? this.getCompleteStyleDeclaration(i.lineIndex, i.charIndex)
          : this._getStyleDeclaration(i.lineIndex, i.charIndex)) || {}
      );
    },
    setSelectionStyles: function(t, e, i) {
      void 0 === e && (e = this.selectionStart || 0),
        void 0 === i && (i = this.selectionEnd || e);
      for (var r = e; r < i; r++) this._extendStyles(r, t);
      return (this._forceClearCache = !0), this;
    },
    _getStyleDeclaration: function(t, e) {
      var i = this.styles && this.styles[t];
      return i ? i[e] : null;
    },
    getCompleteStyleDeclaration: function(t, e) {
      for (
        var i, r = this._getStyleDeclaration(t, e) || {}, n = {}, s = 0;
        s < this._styleProperties.length;
        s++
      )
        n[(i = this._styleProperties[s])] = void 0 === r[i] ? this[i] : r[i];
      return n;
    },
    _setStyleDeclaration: function(t, e, i) {
      this.styles[t][e] = i;
    },
    _deleteStyleDeclaration: function(t, e) {
      delete this.styles[t][e];
    },
    _getLineStyle: function(t) {
      return this.styles[t];
    },
    _setLineStyle: function(t, e) {
      this.styles[t] = e;
    },
    _deleteLineStyle: function(t) {
      delete this.styles[t];
    },
  }),
  (function() {
    function n(t) {
      t.textDecoration &&
        (-1 < t.textDecoration.indexOf('underline') && (t.underline = !0),
        -1 < t.textDecoration.indexOf('line-through') && (t.linethrough = !0),
        -1 < t.textDecoration.indexOf('overline') && (t.overline = !0),
        delete t.textDecoration);
    }
    (fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, {
      type: 'i-text',
      selectionStart: 0,
      selectionEnd: 0,
      selectionColor: 'rgba(17,119,255,0.3)',
      isEditing: !1,
      editable: !0,
      editingBorderColor: 'rgba(102,153,255,0.25)',
      cursorWidth: 2,
      cursorColor: '#333',
      cursorDelay: 1e3,
      cursorDuration: 600,
      caching: !0,
      _reSpace: /\s|\n/,
      _currentCursorOpacity: 0,
      _selectionDirection: null,
      _abortCursorAnimation: !1,
      __widthOfSpace: [],
      inCompositionMode: !1,
      initialize: function(t, e) {
        this.callSuper('initialize', t, e), this.initBehavior();
      },
      setSelectionStart: function(t) {
        (t = Math.max(t, 0)), this._updateAndFire('selectionStart', t);
      },
      setSelectionEnd: function(t) {
        (t = Math.min(t, this.text.length)),
          this._updateAndFire('selectionEnd', t);
      },
      _updateAndFire: function(t, e) {
        this[t] !== e && (this._fireSelectionChanged(), (this[t] = e)),
          this._updateTextarea();
      },
      _fireSelectionChanged: function() {
        this.fire('selection:changed'),
          this.canvas &&
            this.canvas.fire('text:selection:changed', { target: this });
      },
      initDimensions: function() {
        this.isEditing && this.initDelayedCursor(),
          this.clearContextTop(),
          this.callSuper('initDimensions');
      },
      render: function(t) {
        this.clearContextTop(),
          this.callSuper('render', t),
          (this.cursorOffsetCache = {}),
          this.renderCursorOrSelection();
      },
      _render: function(t) {
        this.callSuper('_render', t);
      },
      clearContextTop: function(t) {
        if (this.isEditing && this.canvas && this.canvas.contextTop) {
          var e = this.canvas.contextTop,
            i = this.canvas.viewportTransform;
          e.save(),
            e.transform(i[0], i[1], i[2], i[3], i[4], i[5]),
            this.transform(e),
            this.transformMatrix && e.transform.apply(e, this.transformMatrix),
            this._clearTextArea(e),
            t || e.restore();
        }
      },
      renderCursorOrSelection: function() {
        if (this.isEditing && this.canvas) {
          var t,
            e = this._getCursorBoundaries();
          this.canvas && this.canvas.contextTop
            ? ((t = this.canvas.contextTop), this.clearContextTop(!0))
            : (t = this.canvas.contextContainer).save(),
            this.selectionStart === this.selectionEnd
              ? this.renderCursor(e, t)
              : this.renderSelection(e, t),
            t.restore();
        }
      },
      _clearTextArea: function(t) {
        var e = this.width + 4,
          i = this.height + 4;
        t.clearRect(-e / 2, -i / 2, e, i);
      },
      _getCursorBoundaries: function(t) {
        void 0 === t && (t = this.selectionStart);
        var e = this._getLeftOffset(),
          i = this._getTopOffset(),
          r = this._getCursorBoundariesOffsets(t);
        return { left: e, top: i, leftOffset: r.left, topOffset: r.top };
      },
      _getCursorBoundariesOffsets: function(t) {
        if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache)
          return this.cursorOffsetCache;
        var e,
          i,
          r,
          n,
          s = 0,
          o = 0,
          a = this.get2DCursorLocation(t);
        (r = a.charIndex), (i = a.lineIndex);
        for (var h = 0; h < i; h++) s += this.getHeightOfLine(h);
        e = this._getLineLeftOffset(i);
        var c = this.__charBounds[i][r];
        return (
          c && (o = c.left),
          0 !== this.charSpacing &&
            r === this._textLines[i].length &&
            (o -= this._getWidthOfCharSpacing()),
          (n = { top: s, left: e + (0 < o ? o : 0) }),
          (this.cursorOffsetCache = n),
          this.cursorOffsetCache
        );
      },
      renderCursor: function(t, e) {
        var i = this.get2DCursorLocation(),
          r = i.lineIndex,
          n = 0 < i.charIndex ? i.charIndex - 1 : 0,
          s = this.getValueOfPropertyAt(r, n, 'fontSize'),
          o = this.scaleX * this.canvas.getZoom(),
          a = this.cursorWidth / o,
          h = t.topOffset,
          c = this.getValueOfPropertyAt(r, n, 'deltaY');
        (h +=
          ((1 - this._fontSizeFraction) * this.getHeightOfLine(r)) /
            this.lineHeight -
          s * (1 - this._fontSizeFraction)),
          this.inCompositionMode && this.renderSelection(t, e),
          (e.fillStyle = this.getValueOfPropertyAt(r, n, 'fill')),
          (e.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity),
          e.fillRect(t.left + t.leftOffset - a / 2, h + t.top + c, a, s);
      },
      renderSelection: function(t, e) {
        for (
          var i = this.inCompositionMode
              ? this.hiddenTextarea.selectionStart
              : this.selectionStart,
            r = this.inCompositionMode
              ? this.hiddenTextarea.selectionEnd
              : this.selectionEnd,
            n = -1 !== this.textAlign.indexOf('justify'),
            s = this.get2DCursorLocation(i),
            o = this.get2DCursorLocation(r),
            a = s.lineIndex,
            h = o.lineIndex,
            c = s.charIndex < 0 ? 0 : s.charIndex,
            l = o.charIndex < 0 ? 0 : o.charIndex,
            u = a;
          u <= h;
          u++
        ) {
          var f,
            d = this._getLineLeftOffset(u) || 0,
            g = this.getHeightOfLine(u),
            p = 0,
            v = 0;
          if ((u === a && (p = this.__charBounds[a][c].left), a <= u && u < h))
            v =
              n && !this.isEndOfWrapping(u)
                ? this.width
                : this.getLineWidth(u) || 5;
          else if (u === h)
            if (0 === l) v = this.__charBounds[h][l].left;
            else {
              var m = this._getWidthOfCharSpacing();
              v =
                this.__charBounds[h][l - 1].left +
                this.__charBounds[h][l - 1].width -
                m;
            }
          (f = g),
            (this.lineHeight < 1 || (u === h && 1 < this.lineHeight)) &&
              (g /= this.lineHeight),
            this.inCompositionMode
              ? ((e.fillStyle = this.compositionColor || 'black'),
                e.fillRect(t.left + d + p, t.top + t.topOffset + g, v - p, 1))
              : ((e.fillStyle = this.selectionColor),
                e.fillRect(t.left + d + p, t.top + t.topOffset, v - p, g)),
            (t.topOffset += f);
        }
      },
      getCurrentCharFontSize: function() {
        var t = this._getCurrentCharIndex();
        return this.getValueOfPropertyAt(t.l, t.c, 'fontSize');
      },
      getCurrentCharColor: function() {
        var t = this._getCurrentCharIndex();
        return this.getValueOfPropertyAt(t.l, t.c, 'fill');
      },
      _getCurrentCharIndex: function() {
        var t = this.get2DCursorLocation(this.selectionStart, !0),
          e = 0 < t.charIndex ? t.charIndex - 1 : 0;
        return { l: t.lineIndex, c: e };
      },
    })),
      (fabric.IText.fromObject = function(t, e) {
        if ((n(t), t.styles))
          for (var i in t.styles) for (var r in t.styles[i]) n(t.styles[i][r]);
        fabric.Object._fromObject('IText', t, e, 'text');
      });
  })(),
  (function() {
    var c = fabric.util.object.clone;
    fabric.util.object.extend(fabric.IText.prototype, {
      initBehavior: function() {
        this.initAddedHandler(),
          this.initRemovedHandler(),
          this.initCursorSelectionHandlers(),
          this.initDoubleClickSimulation(),
          (this.mouseMoveHandler = this.mouseMoveHandler.bind(this));
      },
      onDeselect: function() {
        this.isEditing && this.exitEditing(), (this.selected = !1);
      },
      initAddedHandler: function() {
        var e = this;
        this.on('added', function() {
          var t = e.canvas;
          t &&
            (t._hasITextHandlers ||
              ((t._hasITextHandlers = !0), e._initCanvasHandlers(t)),
            (t._iTextInstances = t._iTextInstances || []),
            t._iTextInstances.push(e));
        });
      },
      initRemovedHandler: function() {
        var e = this;
        this.on('removed', function() {
          var t = e.canvas;
          t &&
            ((t._iTextInstances = t._iTextInstances || []),
            fabric.util.removeFromArray(t._iTextInstances, e),
            0 === t._iTextInstances.length &&
              ((t._hasITextHandlers = !1), e._removeCanvasHandlers(t)));
        });
      },
      _initCanvasHandlers: function(t) {
        (t._mouseUpITextHandler = function() {
          t._iTextInstances &&
            t._iTextInstances.forEach(function(t) {
              t.__isMousedown = !1;
            });
        }),
          t.on('mouse:up', t._mouseUpITextHandler);
      },
      _removeCanvasHandlers: function(t) {
        t.off('mouse:up', t._mouseUpITextHandler);
      },
      _tick: function() {
        this._currentTickState = this._animateCursor(
          this,
          1,
          this.cursorDuration,
          '_onTickComplete'
        );
      },
      _animateCursor: function(t, e, i, r) {
        var n;
        return (
          (n = {
            isAborted: !1,
            abort: function() {
              this.isAborted = !0;
            },
          }),
          t.animate('_currentCursorOpacity', e, {
            duration: i,
            onComplete: function() {
              n.isAborted || t[r]();
            },
            onChange: function() {
              t.canvas &&
                t.selectionStart === t.selectionEnd &&
                t.renderCursorOrSelection();
            },
            abort: function() {
              return n.isAborted;
            },
          }),
          n
        );
      },
      _onTickComplete: function() {
        var t = this;
        this._cursorTimeout1 && clearTimeout(this._cursorTimeout1),
          (this._cursorTimeout1 = setTimeout(function() {
            t._currentTickCompleteState = t._animateCursor(
              t,
              0,
              this.cursorDuration / 2,
              '_tick'
            );
          }, 100));
      },
      initDelayedCursor: function(t) {
        var e = this,
          i = t ? 0 : this.cursorDelay;
        this.abortCursorAnimation(),
          (this._currentCursorOpacity = 1),
          (this._cursorTimeout2 = setTimeout(function() {
            e._tick();
          }, i));
      },
      abortCursorAnimation: function() {
        var t = this._currentTickState || this._currentTickCompleteState,
          e = this.canvas;
        this._currentTickState && this._currentTickState.abort(),
          this._currentTickCompleteState &&
            this._currentTickCompleteState.abort(),
          clearTimeout(this._cursorTimeout1),
          clearTimeout(this._cursorTimeout2),
          (this._currentCursorOpacity = 0),
          t && e && e.clearContext(e.contextTop || e.contextContainer);
      },
      selectAll: function() {
        return (
          (this.selectionStart = 0),
          (this.selectionEnd = this._text.length),
          this._fireSelectionChanged(),
          this._updateTextarea(),
          this
        );
      },
      getSelectedText: function() {
        return this._text
          .slice(this.selectionStart, this.selectionEnd)
          .join('');
      },
      findWordBoundaryLeft: function(t) {
        var e = 0,
          i = t - 1;
        if (this._reSpace.test(this._text[i]))
          for (; this._reSpace.test(this._text[i]); ) e++, i--;
        for (; /\S/.test(this._text[i]) && -1 < i; ) e++, i--;
        return t - e;
      },
      findWordBoundaryRight: function(t) {
        var e = 0,
          i = t;
        if (this._reSpace.test(this._text[i]))
          for (; this._reSpace.test(this._text[i]); ) e++, i++;
        for (; /\S/.test(this._text[i]) && i < this.text.length; ) e++, i++;
        return t + e;
      },
      findLineBoundaryLeft: function(t) {
        for (var e = 0, i = t - 1; !/\n/.test(this._text[i]) && -1 < i; )
          e++, i--;
        return t - e;
      },
      findLineBoundaryRight: function(t) {
        for (
          var e = 0, i = t;
          !/\n/.test(this._text[i]) && i < this.text.length;

        )
          e++, i++;
        return t + e;
      },
      searchWordBoundary: function(t, e) {
        for (
          var i = this._reSpace.test(this.text.charAt(t)) ? t - 1 : t,
            r = this.text.charAt(i),
            n = /[ \n\.,;!\?\-]/;
          !n.test(r) && 0 < i && i < this.text.length;

        )
          (i += e), (r = this.text.charAt(i));
        return n.test(r) && '\n' !== r && (i += 1 === e ? 0 : 1), i;
      },
      selectWord: function(t) {
        t = t || this.selectionStart;
        var e = this.searchWordBoundary(t, -1),
          i = this.searchWordBoundary(t, 1);
        (this.selectionStart = e),
          (this.selectionEnd = i),
          this._fireSelectionChanged(),
          this._updateTextarea(),
          this.renderCursorOrSelection();
      },
      selectLine: function(t) {
        t = t || this.selectionStart;
        var e = this.findLineBoundaryLeft(t),
          i = this.findLineBoundaryRight(t);
        return (
          (this.selectionStart = e),
          (this.selectionEnd = i),
          this._fireSelectionChanged(),
          this._updateTextarea(),
          this
        );
      },
      enterEditing: function(t) {
        if (!this.isEditing && this.editable)
          return (
            this.canvas &&
              (this.canvas.calcOffset(), this.exitEditingOnOthers(this.canvas)),
            (this.isEditing = !0),
            this.initHiddenTextarea(t),
            this.hiddenTextarea.focus(),
            (this.hiddenTextarea.value = this.text),
            this._updateTextarea(),
            this._saveEditingProps(),
            this._setEditingProps(),
            (this._textBeforeEdit = this.text),
            this._tick(),
            this.fire('editing:entered'),
            this._fireSelectionChanged(),
            this.canvas &&
              (this.canvas.fire('text:editing:entered', { target: this }),
              this.initMouseMoveHandler(),
              this.canvas.requestRenderAll()),
            this
          );
      },
      exitEditingOnOthers: function(t) {
        t._iTextInstances &&
          t._iTextInstances.forEach(function(t) {
            (t.selected = !1), t.isEditing && t.exitEditing();
          });
      },
      initMouseMoveHandler: function() {
        this.canvas.on('mouse:move', this.mouseMoveHandler);
      },
      mouseMoveHandler: function(t) {
        if (this.__isMousedown && this.isEditing) {
          var e = this.getSelectionStartFromPointer(t.e),
            i = this.selectionStart,
            r = this.selectionEnd;
          ((e === this.__selectionStartOnMouseDown && i !== r) ||
            (i !== e && r !== e)) &&
            (e > this.__selectionStartOnMouseDown
              ? ((this.selectionStart = this.__selectionStartOnMouseDown),
                (this.selectionEnd = e))
              : ((this.selectionStart = e),
                (this.selectionEnd = this.__selectionStartOnMouseDown)),
            (this.selectionStart === i && this.selectionEnd === r) ||
              (this.restartCursorIfNeeded(),
              this._fireSelectionChanged(),
              this._updateTextarea(),
              this.renderCursorOrSelection()));
        }
      },
      _setEditingProps: function() {
        (this.hoverCursor = 'text'),
          this.canvas &&
            (this.canvas.defaultCursor = this.canvas.moveCursor = 'text'),
          (this.borderColor = this.editingBorderColor),
          (this.hasControls = this.selectable = !1),
          (this.lockMovementX = this.lockMovementY = !0);
      },
      fromStringToGraphemeSelection: function(t, e, i) {
        var r = i.slice(0, t),
          n = fabric.util.string.graphemeSplit(r).length;
        if (t === e) return { selectionStart: n, selectionEnd: n };
        var s = i.slice(t, e);
        return {
          selectionStart: n,
          selectionEnd: n + fabric.util.string.graphemeSplit(s).length,
        };
      },
      fromGraphemeToStringSelection: function(t, e, i) {
        var r = i.slice(0, t).join('').length;
        return t === e
          ? { selectionStart: r, selectionEnd: r }
          : {
              selectionStart: r,
              selectionEnd: r + i.slice(t, e).join('').length,
            };
      },
      _updateTextarea: function() {
        if (((this.cursorOffsetCache = {}), this.hiddenTextarea)) {
          if (!this.inCompositionMode) {
            var t = this.fromGraphemeToStringSelection(
              this.selectionStart,
              this.selectionEnd,
              this._text
            );
            (this.hiddenTextarea.selectionStart = t.selectionStart),
              (this.hiddenTextarea.selectionEnd = t.selectionEnd);
          }
          this.updateTextareaPosition();
        }
      },
      updateFromTextArea: function() {
        if (this.hiddenTextarea) {
          (this.cursorOffsetCache = {}),
            (this.text = this.hiddenTextarea.value),
            this._shouldClearDimensionCache() &&
              (this.initDimensions(), this.setCoords());
          var t = this.fromStringToGraphemeSelection(
            this.hiddenTextarea.selectionStart,
            this.hiddenTextarea.selectionEnd,
            this.hiddenTextarea.value
          );
          (this.selectionEnd = this.selectionStart = t.selectionEnd),
            this.inCompositionMode || (this.selectionStart = t.selectionStart),
            this.updateTextareaPosition();
        }
      },
      updateTextareaPosition: function() {
        if (this.selectionStart === this.selectionEnd) {
          var t = this._calcTextareaPosition();
          (this.hiddenTextarea.style.left = t.left),
            (this.hiddenTextarea.style.top = t.top);
        }
      },
      _calcTextareaPosition: function() {
        if (!this.canvas) return { x: 1, y: 1 };
        var t = this.inCompositionMode
            ? this.compositionStart
            : this.selectionStart,
          e = this._getCursorBoundaries(t),
          i = this.get2DCursorLocation(t),
          r = i.lineIndex,
          n = i.charIndex,
          s = this.getValueOfPropertyAt(r, n, 'fontSize') * this.lineHeight,
          o = e.leftOffset,
          a = this.calcTransformMatrix(),
          h = { x: e.left + o, y: e.top + e.topOffset + s },
          c = this.canvas.upperCanvasEl,
          l = c.width,
          u = c.height,
          f = l - s,
          d = u - s,
          g = c.clientWidth / l,
          p = c.clientHeight / u;
        return (
          (h = fabric.util.transformPoint(h, a)),
          ((h = fabric.util.transformPoint(
            h,
            this.canvas.viewportTransform
          )).x *= g),
          (h.y *= p),
          h.x < 0 && (h.x = 0),
          h.x > f && (h.x = f),
          h.y < 0 && (h.y = 0),
          h.y > d && (h.y = d),
          (h.x += this.canvas._offset.left),
          (h.y += this.canvas._offset.top),
          {
            left: h.x + 'px',
            top: h.y + 'px',
            fontSize: s + 'px',
            charHeight: s,
          }
        );
      },
      _saveEditingProps: function() {
        this._savedProps = {
          hasControls: this.hasControls,
          borderColor: this.borderColor,
          lockMovementX: this.lockMovementX,
          lockMovementY: this.lockMovementY,
          hoverCursor: this.hoverCursor,
          defaultCursor: this.canvas && this.canvas.defaultCursor,
          moveCursor: this.canvas && this.canvas.moveCursor,
        };
      },
      _restoreEditingProps: function() {
        this._savedProps &&
          ((this.hoverCursor = this._savedProps.hoverCursor),
          (this.hasControls = this._savedProps.hasControls),
          (this.borderColor = this._savedProps.borderColor),
          (this.lockMovementX = this._savedProps.lockMovementX),
          (this.lockMovementY = this._savedProps.lockMovementY),
          this.canvas &&
            ((this.canvas.defaultCursor = this._savedProps.defaultCursor),
            (this.canvas.moveCursor = this._savedProps.moveCursor)));
      },
      exitEditing: function() {
        var t = this._textBeforeEdit !== this.text;
        return (
          (this.selected = !1),
          (this.isEditing = !1),
          (this.selectable = !0),
          (this.selectionEnd = this.selectionStart),
          this.hiddenTextarea &&
            (this.hiddenTextarea.blur && this.hiddenTextarea.blur(),
            this.canvas &&
              this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea),
            (this.hiddenTextarea = null)),
          this.abortCursorAnimation(),
          this._restoreEditingProps(),
          (this._currentCursorOpacity = 0),
          this._shouldClearDimensionCache() &&
            (this.initDimensions(), this.setCoords()),
          this.fire('editing:exited'),
          t && this.fire('modified'),
          this.canvas &&
            (this.canvas.off('mouse:move', this.mouseMoveHandler),
            this.canvas.fire('text:editing:exited', { target: this }),
            t && this.canvas.fire('object:modified', { target: this })),
          this
        );
      },
      _removeExtraneousStyles: function() {
        for (var t in this.styles) this._textLines[t] || delete this.styles[t];
      },
      removeStyleFromTo: function(t, e) {
        var i,
          r,
          n = this.get2DCursorLocation(t, !0),
          s = this.get2DCursorLocation(e, !0),
          o = n.lineIndex,
          a = n.charIndex,
          h = s.lineIndex,
          c = s.charIndex;
        if (o !== h) {
          if (this.styles[o])
            for (i = a; i < this._unwrappedTextLines[o].length; i++)
              delete this.styles[o][i];
          if (this.styles[h])
            for (i = c; i < this._unwrappedTextLines[h].length; i++)
              (r = this.styles[h][i]) &&
                (this.styles[o] || (this.styles[o] = {}),
                (this.styles[o][a + i - c] = r));
          for (i = o + 1; i <= h; i++) delete this.styles[i];
          this.shiftLineStyles(h, o - h);
        } else if (this.styles[o]) {
          r = this.styles[o];
          var l,
            u,
            f = c - a;
          for (i = a; i < c; i++) delete r[i];
          for (u in this.styles[o])
            c <= (l = parseInt(u, 10)) && ((r[l - f] = r[u]), delete r[u]);
        }
      },
      shiftLineStyles: function(t, e) {
        var i = c(this.styles);
        for (var r in this.styles) {
          var n = parseInt(r, 10);
          t < n &&
            ((this.styles[n + e] = i[n]), i[n - e] || delete this.styles[n]);
        }
      },
      restartCursorIfNeeded: function() {
        (this._currentTickState &&
          !this._currentTickState.isAborted &&
          this._currentTickCompleteState &&
          !this._currentTickCompleteState.isAborted) ||
          this.initDelayedCursor();
      },
      insertNewlineStyleObject: function(t, e, i, r) {
        var n,
          s = {},
          o = !1;
        for (var a in (i || (i = 1),
        this.shiftLineStyles(t, i),
        this.styles[t] && (n = this.styles[t][0 === e ? e : e - 1]),
        this.styles[t])) {
          var h = parseInt(a, 10);
          e <= h &&
            ((o = !0),
            (s[h - e] = this.styles[t][a]),
            delete this.styles[t][a]);
        }
        for (o ? (this.styles[t + i] = s) : delete this.styles[t + i]; 1 < i; )
          i--,
            r && r[i]
              ? (this.styles[t + i] = { 0: c(r[i]) })
              : n
              ? (this.styles[t + i] = { 0: c(n) })
              : delete this.styles[t + i];
        this._forceClearCache = !0;
      },
      insertCharStyleObject: function(t, e, i, r) {
        this.styles || (this.styles = {});
        var n = this.styles[t],
          s = n ? c(n) : {};
        for (var o in (i || (i = 1), s)) {
          var a = parseInt(o, 10);
          e <= a && ((n[a + i] = s[a]), s[a - i] || delete n[a]);
        }
        if (((this._forceClearCache = !0), r))
          for (; i--; )
            Object.keys(r[i]).length &&
              (this.styles[t] || (this.styles[t] = {}),
              (this.styles[t][e + i] = c(r[i])));
        else if (n)
          for (var h = n[e ? e - 1 : 1]; h && i--; )
            this.styles[t][e + i] = c(h);
      },
      insertNewStyleBlock: function(t, e, i) {
        for (
          var r = this.get2DCursorLocation(e, !0), n = [0], s = 0, o = 0;
          o < t.length;
          o++
        )
          '\n' === t[o] ? (n[++s] = 0) : n[s]++;
        0 < n[0] &&
          (this.insertCharStyleObject(r.lineIndex, r.charIndex, n[0], i),
          (i = i && i.slice(n[0] + 1))),
          s &&
            this.insertNewlineStyleObject(r.lineIndex, r.charIndex + n[0], s);
        for (o = 1; o < s; o++)
          0 < n[o]
            ? this.insertCharStyleObject(r.lineIndex + o, 0, n[o], i)
            : i && (this.styles[r.lineIndex + o][0] = i[0]),
            (i = i && i.slice(n[o] + 1));
        0 < n[o] && this.insertCharStyleObject(r.lineIndex + o, 0, n[o], i);
      },
      setSelectionStartEndWithShift: function(t, e, i) {
        i <= t
          ? (e === t
              ? (this._selectionDirection = 'left')
              : 'right' === this._selectionDirection &&
                ((this._selectionDirection = 'left'), (this.selectionEnd = t)),
            (this.selectionStart = i))
          : t < i && i < e
          ? 'right' === this._selectionDirection
            ? (this.selectionEnd = i)
            : (this.selectionStart = i)
          : (e === t
              ? (this._selectionDirection = 'right')
              : 'left' === this._selectionDirection &&
                ((this._selectionDirection = 'right'),
                (this.selectionStart = e)),
            (this.selectionEnd = i));
      },
      setSelectionInBoundaries: function() {
        var t = this.text.length;
        this.selectionStart > t
          ? (this.selectionStart = t)
          : this.selectionStart < 0 && (this.selectionStart = 0),
          this.selectionEnd > t
            ? (this.selectionEnd = t)
            : this.selectionEnd < 0 && (this.selectionEnd = 0);
      },
    });
  })(),
  fabric.util.object.extend(fabric.IText.prototype, {
    initDoubleClickSimulation: function() {
      (this.__lastClickTime = +new Date()),
        (this.__lastLastClickTime = +new Date()),
        (this.__lastPointer = {}),
        this.on('mousedown', this.onMouseDown);
    },
    onMouseDown: function(t) {
      if (this.canvas) {
        this.__newClickTime = +new Date();
        var e = t.pointer;
        this.isTripleClick(e) &&
          (this.fire('tripleclick', t), this._stopEvent(t.e)),
          (this.__lastLastClickTime = this.__lastClickTime),
          (this.__lastClickTime = this.__newClickTime),
          (this.__lastPointer = e),
          (this.__lastIsEditing = this.isEditing),
          (this.__lastSelected = this.selected);
      }
    },
    isTripleClick: function(t) {
      return (
        this.__newClickTime - this.__lastClickTime < 500 &&
        this.__lastClickTime - this.__lastLastClickTime < 500 &&
        this.__lastPointer.x === t.x &&
        this.__lastPointer.y === t.y
      );
    },
    _stopEvent: function(t) {
      t.preventDefault && t.preventDefault(),
        t.stopPropagation && t.stopPropagation();
    },
    initCursorSelectionHandlers: function() {
      this.initMousedownHandler(), this.initMouseupHandler(), this.initClicks();
    },
    initClicks: function() {
      this.on('mousedblclick', function(t) {
        this.selectWord(this.getSelectionStartFromPointer(t.e));
      }),
        this.on('tripleclick', function(t) {
          this.selectLine(this.getSelectionStartFromPointer(t.e));
        });
    },
    _mouseDownHandler: function(t) {
      !this.canvas ||
        !this.editable ||
        (t.e.button && 1 !== t.e.button) ||
        ((this.__isMousedown = !0),
        this.selected && this.setCursorByClick(t.e),
        this.isEditing &&
          ((this.__selectionStartOnMouseDown = this.selectionStart),
          this.selectionStart === this.selectionEnd &&
            this.abortCursorAnimation(),
          this.renderCursorOrSelection()));
    },
    _mouseDownHandlerBefore: function(t) {
      !this.canvas ||
        !this.editable ||
        (t.e.button && 1 !== t.e.button) ||
        (this === this.canvas._activeObject && (this.selected = !0));
    },
    initMousedownHandler: function() {
      this.on('mousedown', this._mouseDownHandler),
        this.on('mousedown:before', this._mouseDownHandlerBefore);
    },
    initMouseupHandler: function() {
      this.on('mouseup', this.mouseUpHandler);
    },
    mouseUpHandler: function(t) {
      if (
        ((this.__isMousedown = !1),
        !(
          !this.editable ||
          this.group ||
          (t.transform && t.transform.actionPerformed) ||
          (t.e.button && 1 !== t.e.button)
        ))
      ) {
        if (this.canvas) {
          var e = this.canvas._activeObject;
          if (e && e !== this) return;
        }
        this.__lastSelected && !this.__corner
          ? ((this.selected = !1),
            (this.__lastSelected = !1),
            this.enterEditing(t.e),
            this.selectionStart === this.selectionEnd
              ? this.initDelayedCursor(!0)
              : this.renderCursorOrSelection())
          : (this.selected = !0);
      }
    },
    setCursorByClick: function(t) {
      var e = this.getSelectionStartFromPointer(t),
        i = this.selectionStart,
        r = this.selectionEnd;
      t.shiftKey
        ? this.setSelectionStartEndWithShift(i, r, e)
        : ((this.selectionStart = e), (this.selectionEnd = e)),
        this.isEditing &&
          (this._fireSelectionChanged(), this._updateTextarea());
    },
    getSelectionStartFromPointer: function(t) {
      for (
        var e = this.getLocalPointer(t),
          i = 0,
          r = 0,
          n = 0,
          s = 0,
          o = 0,
          a = 0,
          h = this._textLines.length;
        a < h && n <= e.y;
        a++
      )
        (n += this.getHeightOfLine(a) * this.scaleY),
          0 < (o = a) && (s += this._textLines[a - 1].length + 1);
      r = this._getLineLeftOffset(o) * this.scaleX;
      for (
        var c = 0, l = this._textLines[o].length;
        c < l &&
        ((i = r),
        (r += this.__charBounds[o][c].kernedWidth * this.scaleX) <= e.x);
        c++
      )
        s++;
      return this._getNewSelectionStartFromOffset(e, i, r, s, l);
    },
    _getNewSelectionStartFromOffset: function(t, e, i, r, n) {
      var s = t.x - e,
        o = i - t.x,
        a = r + (s < o || o < 0 ? 0 : 1);
      return (
        this.flipX && (a = n - a),
        a > this._text.length && (a = this._text.length),
        a
      );
    },
  }),
  fabric.util.object.extend(fabric.IText.prototype, {
    initHiddenTextarea: function() {
      (this.hiddenTextarea = fabric.document.createElement('textarea')),
        this.hiddenTextarea.setAttribute('autocapitalize', 'off'),
        this.hiddenTextarea.setAttribute('autocorrect', 'off'),
        this.hiddenTextarea.setAttribute('autocomplete', 'off'),
        this.hiddenTextarea.setAttribute('spellcheck', 'false'),
        this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', ''),
        this.hiddenTextarea.setAttribute('wrap', 'off');
      var t = this._calcTextareaPosition();
      (this.hiddenTextarea.style.cssText =
        'position: absolute; top: ' +
        t.top +
        '; left: ' +
        t.left +
        '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; paddingｰtop: ' +
        t.fontSize +
        ';'),
        fabric.document.body.appendChild(this.hiddenTextarea),
        fabric.util.addListener(
          this.hiddenTextarea,
          'keydown',
          this.onKeyDown.bind(this)
        ),
        fabric.util.addListener(
          this.hiddenTextarea,
          'keyup',
          this.onKeyUp.bind(this)
        ),
        fabric.util.addListener(
          this.hiddenTextarea,
          'input',
          this.onInput.bind(this)
        ),
        fabric.util.addListener(
          this.hiddenTextarea,
          'copy',
          this.copy.bind(this)
        ),
        fabric.util.addListener(
          this.hiddenTextarea,
          'cut',
          this.copy.bind(this)
        ),
        fabric.util.addListener(
          this.hiddenTextarea,
          'paste',
          this.paste.bind(this)
        ),
        fabric.util.addListener(
          this.hiddenTextarea,
          'compositionstart',
          this.onCompositionStart.bind(this)
        ),
        fabric.util.addListener(
          this.hiddenTextarea,
          'compositionupdate',
          this.onCompositionUpdate.bind(this)
        ),
        fabric.util.addListener(
          this.hiddenTextarea,
          'compositionend',
          this.onCompositionEnd.bind(this)
        ),
        !this._clickHandlerInitialized &&
          this.canvas &&
          (fabric.util.addListener(
            this.canvas.upperCanvasEl,
            'click',
            this.onClick.bind(this)
          ),
          (this._clickHandlerInitialized = !0));
    },
    keysMap: {
      9: 'exitEditing',
      27: 'exitEditing',
      33: 'moveCursorUp',
      34: 'moveCursorDown',
      35: 'moveCursorRight',
      36: 'moveCursorLeft',
      37: 'moveCursorLeft',
      38: 'moveCursorUp',
      39: 'moveCursorRight',
      40: 'moveCursorDown',
    },
    ctrlKeysMapUp: { 67: 'copy', 88: 'cut' },
    ctrlKeysMapDown: { 65: 'selectAll' },
    onClick: function() {
      this.hiddenTextarea && this.hiddenTextarea.focus();
    },
    onKeyDown: function(t) {
      if (this.isEditing && !this.inCompositionMode) {
        if (t.keyCode in this.keysMap) this[this.keysMap[t.keyCode]](t);
        else {
          if (!(t.keyCode in this.ctrlKeysMapDown && (t.ctrlKey || t.metaKey)))
            return;
          this[this.ctrlKeysMapDown[t.keyCode]](t);
        }
        t.stopImmediatePropagation(),
          t.preventDefault(),
          33 <= t.keyCode && t.keyCode <= 40
            ? (this.clearContextTop(), this.renderCursorOrSelection())
            : this.canvas && this.canvas.requestRenderAll();
      }
    },
    onKeyUp: function(t) {
      !this.isEditing || this._copyDone || this.inCompositionMode
        ? (this._copyDone = !1)
        : t.keyCode in this.ctrlKeysMapUp &&
          (t.ctrlKey || t.metaKey) &&
          (this[this.ctrlKeysMapUp[t.keyCode]](t),
          t.stopImmediatePropagation(),
          t.preventDefault(),
          this.canvas && this.canvas.requestRenderAll());
    },
    onInput: function(t) {
      var e = this.fromPaste;
      if (((this.fromPaste = !1), t && t.stopPropagation(), this.isEditing)) {
        var i,
          r,
          n = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,
          s = this._text.length,
          o = n.length,
          a = o - s;
        if ('' === this.hiddenTextarea.value)
          return (
            (this.styles = {}),
            this.updateFromTextArea(),
            this.fire('changed'),
            void (
              this.canvas &&
              (this.canvas.fire('text:changed', { target: this }),
              this.canvas.requestRenderAll())
            )
          );
        var h = this.fromStringToGraphemeSelection(
            this.hiddenTextarea.selectionStart,
            this.hiddenTextarea.selectionEnd,
            this.hiddenTextarea.value
          ),
          c = this.selectionStart > h.selectionStart;
        this.selectionStart !== this.selectionEnd
          ? ((i = this._text.slice(this.selectionStart, this.selectionEnd)),
            (a += this.selectionEnd - this.selectionStart))
          : o < s &&
            (i = c
              ? this._text.slice(this.selectionEnd + a, this.selectionEnd)
              : this._text.slice(this.selectionStart, this.selectionStart - a)),
          (r = n.slice(h.selectionEnd - a, h.selectionEnd)),
          i &&
            i.length &&
            (this.selectionStart !== this.selectionEnd
              ? this.removeStyleFromTo(this.selectionStart, this.selectionEnd)
              : c
              ? this.removeStyleFromTo(
                  this.selectionEnd - i.length,
                  this.selectionEnd
                )
              : this.removeStyleFromTo(
                  this.selectionEnd,
                  this.selectionEnd + i.length
                )),
          r.length &&
            (e && r.join('') === fabric.copiedText
              ? this.insertNewStyleBlock(
                  r,
                  this.selectionStart,
                  fabric.copiedTextStyle
                )
              : this.insertNewStyleBlock(r, this.selectionStart)),
          this.updateFromTextArea(),
          this.fire('changed'),
          this.canvas &&
            (this.canvas.fire('text:changed', { target: this }),
            this.canvas.requestRenderAll());
      }
    },
    onCompositionStart: function() {
      this.inCompositionMode = !0;
    },
    onCompositionEnd: function() {
      this.inCompositionMode = !1;
    },
    onCompositionUpdate: function(t) {
      (this.compositionStart = t.target.selectionStart),
        (this.compositionEnd = t.target.selectionEnd),
        this.updateTextareaPosition();
    },
    copy: function() {
      this.selectionStart !== this.selectionEnd &&
        ((fabric.copiedText = this.getSelectedText()),
        (fabric.copiedTextStyle = this.getSelectionStyles(
          this.selectionStart,
          this.selectionEnd,
          !0
        )),
        (this._copyDone = !0));
    },
    paste: function() {
      this.fromPaste = !0;
    },
    _getClipboardData: function(t) {
      return (t && t.clipboardData) || fabric.window.clipboardData;
    },
    _getWidthBeforeCursor: function(t, e) {
      var i,
        r = this._getLineLeftOffset(t);
      return (
        0 < e && (r += (i = this.__charBounds[t][e - 1]).left + i.width), r
      );
    },
    getDownCursorOffset: function(t, e) {
      var i = this._getSelectionForOffset(t, e),
        r = this.get2DCursorLocation(i),
        n = r.lineIndex;
      if (n === this._textLines.length - 1 || t.metaKey || 34 === t.keyCode)
        return this._text.length - i;
      var s = r.charIndex,
        o = this._getWidthBeforeCursor(n, s),
        a = this._getIndexOnLine(n + 1, o);
      return this._textLines[n].slice(s).length + a + 2;
    },
    _getSelectionForOffset: function(t, e) {
      return t.shiftKey && this.selectionStart !== this.selectionEnd && e
        ? this.selectionEnd
        : this.selectionStart;
    },
    getUpCursorOffset: function(t, e) {
      var i = this._getSelectionForOffset(t, e),
        r = this.get2DCursorLocation(i),
        n = r.lineIndex;
      if (0 === n || t.metaKey || 33 === t.keyCode) return -i;
      var s = r.charIndex,
        o = this._getWidthBeforeCursor(n, s),
        a = this._getIndexOnLine(n - 1, o),
        h = this._textLines[n].slice(0, s);
      return -this._textLines[n - 1].length + a - h.length;
    },
    _getIndexOnLine: function(t, e) {
      for (
        var i,
          r,
          n = this._textLines[t],
          s = this._getLineLeftOffset(t),
          o = 0,
          a = 0,
          h = n.length;
        a < h;
        a++
      )
        if (e < (s += i = this.__charBounds[t][a].width)) {
          r = !0;
          var c = s - i,
            l = s,
            u = Math.abs(c - e);
          o = Math.abs(l - e) < u ? a : a - 1;
          break;
        }
      return r || (o = n.length - 1), o;
    },
    moveCursorDown: function(t) {
      (this.selectionStart >= this._text.length &&
        this.selectionEnd >= this._text.length) ||
        this._moveCursorUpOrDown('Down', t);
    },
    moveCursorUp: function(t) {
      (0 === this.selectionStart && 0 === this.selectionEnd) ||
        this._moveCursorUpOrDown('Up', t);
    },
    _moveCursorUpOrDown: function(t, e) {
      var i = this['get' + t + 'CursorOffset'](
        e,
        'right' === this._selectionDirection
      );
      e.shiftKey ? this.moveCursorWithShift(i) : this.moveCursorWithoutShift(i),
        0 !== i &&
          (this.setSelectionInBoundaries(),
          this.abortCursorAnimation(),
          (this._currentCursorOpacity = 1),
          this.initDelayedCursor(),
          this._fireSelectionChanged(),
          this._updateTextarea());
    },
    moveCursorWithShift: function(t) {
      var e =
        'left' === this._selectionDirection
          ? this.selectionStart + t
          : this.selectionEnd + t;
      return (
        this.setSelectionStartEndWithShift(
          this.selectionStart,
          this.selectionEnd,
          e
        ),
        0 !== t
      );
    },
    moveCursorWithoutShift: function(t) {
      return (
        t < 0
          ? ((this.selectionStart += t),
            (this.selectionEnd = this.selectionStart))
          : ((this.selectionEnd += t),
            (this.selectionStart = this.selectionEnd)),
        0 !== t
      );
    },
    moveCursorLeft: function(t) {
      (0 === this.selectionStart && 0 === this.selectionEnd) ||
        this._moveCursorLeftOrRight('Left', t);
    },
    _move: function(t, e, i) {
      var r;
      if (t.altKey) r = this['findWordBoundary' + i](this[e]);
      else {
        if (!t.metaKey && 35 !== t.keyCode && 36 !== t.keyCode)
          return (this[e] += 'Left' === i ? -1 : 1), !0;
        r = this['findLineBoundary' + i](this[e]);
      }
      if (void 0 !== typeof r && this[e] !== r) return (this[e] = r), !0;
    },
    _moveLeft: function(t, e) {
      return this._move(t, e, 'Left');
    },
    _moveRight: function(t, e) {
      return this._move(t, e, 'Right');
    },
    moveCursorLeftWithoutShift: function(t) {
      var e = !0;
      return (
        (this._selectionDirection = 'left'),
        this.selectionEnd === this.selectionStart &&
          0 !== this.selectionStart &&
          (e = this._moveLeft(t, 'selectionStart')),
        (this.selectionEnd = this.selectionStart),
        e
      );
    },
    moveCursorLeftWithShift: function(t) {
      return 'right' === this._selectionDirection &&
        this.selectionStart !== this.selectionEnd
        ? this._moveLeft(t, 'selectionEnd')
        : 0 !== this.selectionStart
        ? ((this._selectionDirection = 'left'),
          this._moveLeft(t, 'selectionStart'))
        : void 0;
    },
    moveCursorRight: function(t) {
      (this.selectionStart >= this._text.length &&
        this.selectionEnd >= this._text.length) ||
        this._moveCursorLeftOrRight('Right', t);
    },
    _moveCursorLeftOrRight: function(t, e) {
      var i = 'moveCursor' + t + 'With';
      (this._currentCursorOpacity = 1),
        e.shiftKey ? (i += 'Shift') : (i += 'outShift'),
        this[i](e) &&
          (this.abortCursorAnimation(),
          this.initDelayedCursor(),
          this._fireSelectionChanged(),
          this._updateTextarea());
    },
    moveCursorRightWithShift: function(t) {
      return 'left' === this._selectionDirection &&
        this.selectionStart !== this.selectionEnd
        ? this._moveRight(t, 'selectionStart')
        : this.selectionEnd !== this._text.length
        ? ((this._selectionDirection = 'right'),
          this._moveRight(t, 'selectionEnd'))
        : void 0;
    },
    moveCursorRightWithoutShift: function(t) {
      var e = !0;
      return (
        (this._selectionDirection = 'right'),
        this.selectionStart === this.selectionEnd
          ? ((e = this._moveRight(t, 'selectionStart')),
            (this.selectionEnd = this.selectionStart))
          : (this.selectionStart = this.selectionEnd),
        e
      );
    },
    removeChars: function(t, e) {
      void 0 === e && (e = t + 1),
        this.removeStyleFromTo(t, e),
        this._text.splice(t, e - t),
        (this.text = this._text.join('')),
        this.set('dirty', !0),
        this._shouldClearDimensionCache() &&
          (this.initDimensions(), this.setCoords()),
        this._removeExtraneousStyles();
    },
    insertChars: function(t, e, i, r) {
      void 0 === r && (r = i), i < r && this.removeStyleFromTo(i, r);
      var n = fabric.util.string.graphemeSplit(t);
      this.insertNewStyleBlock(n, i, e),
        (this._text = [].concat(
          this._text.slice(0, i),
          n,
          this._text.slice(r)
        )),
        (this.text = this._text.join('')),
        this.set('dirty', !0),
        this._shouldClearDimensionCache() &&
          (this.initDimensions(), this.setCoords()),
        this._removeExtraneousStyles();
    },
  }),
  (function() {
    var l = fabric.util.toFixed,
      u = /  +/g;
    fabric.util.object.extend(fabric.Text.prototype, {
      toSVG: function(t) {
        var e = this._getSVGLeftTopOffsets(),
          i = this._getSVGTextAndBg(e.textTop, e.textLeft),
          r = this._wrapSVGTextAndBg(i);
        return this._createBaseSVGMarkup(r, {
          reviver: t,
          noStyle: !0,
          withShadow: !0,
        });
      },
      _getSVGLeftTopOffsets: function() {
        return {
          textLeft: -this.width / 2,
          textTop: -this.height / 2,
          lineTop: this.getHeightOfLine(0),
        };
      },
      _wrapSVGTextAndBg: function(t) {
        var e = this.getSvgTextDecoration(this);
        return [
          t.textBgRects.join(''),
          '\t\t<text xml:space="preserve" ',
          this.fontFamily
            ? 'font-family="' + this.fontFamily.replace(/"/g, "'") + '" '
            : '',
          this.fontSize ? 'font-size="' + this.fontSize + '" ' : '',
          this.fontStyle ? 'font-style="' + this.fontStyle + '" ' : '',
          this.fontWeight ? 'font-weight="' + this.fontWeight + '" ' : '',
          e ? 'text-decoration="' + e + '" ' : '',
          'style="',
          this.getSvgStyles(!0),
          '"',
          this.addPaintOrder(),
          ' >',
          t.textSpans.join(''),
          '</text>\n',
        ];
      },
      _getSVGTextAndBg: function(t, e) {
        var i,
          r = [],
          n = [],
          s = t;
        this._setSVGBg(n);
        for (var o = 0, a = this._textLines.length; o < a; o++)
          (i = this._getLineLeftOffset(o)),
            (this.textBackgroundColor ||
              this.styleHas('textBackgroundColor', o)) &&
              this._setSVGTextLineBg(n, o, e + i, s),
            this._setSVGTextLineText(r, o, e + i, s),
            (s += this.getHeightOfLine(o));
        return { textSpans: r, textBgRects: n };
      },
      _createTextCharSpan: function(t, e, i, r) {
        var n = t !== t.trim() || t.match(u),
          s = this.getSvgSpanStyles(e, n),
          o = s ? 'style="' + s + '"' : '',
          a = e.deltaY,
          h = '',
          c = fabric.Object.NUM_FRACTION_DIGITS;
        return (
          a && (h = ' dy="' + l(a, c) + '" '),
          [
            '<tspan x="',
            l(i, c),
            '" y="',
            l(r, c),
            '" ',
            h,
            o,
            '>',
            fabric.util.string.escapeXml(t),
            '</tspan>',
          ].join('')
        );
      },
      _setSVGTextLineText: function(t, e, i, r) {
        var n,
          s,
          o,
          a,
          h,
          c = this.getHeightOfLine(e),
          l = -1 !== this.textAlign.indexOf('justify'),
          u = '',
          f = 0,
          d = this._textLines[e];
        r += (c * (1 - this._fontSizeFraction)) / this.lineHeight;
        for (var g = 0, p = d.length - 1; g <= p; g++)
          (h = g === p || this.charSpacing),
            (u += d[g]),
            (o = this.__charBounds[e][g]),
            0 === f
              ? ((i += o.kernedWidth - o.width), (f += o.width))
              : (f += o.kernedWidth),
            l && !h && this._reSpaceAndTab.test(d[g]) && (h = !0),
            h ||
              ((n = n || this.getCompleteStyleDeclaration(e, g)),
              (s = this.getCompleteStyleDeclaration(e, g + 1)),
              (h = this._hasStyleChangedForSvg(n, s))),
            h &&
              ((a = this._getStyleDeclaration(e, g) || {}),
              t.push(this._createTextCharSpan(u, a, i, r)),
              (u = ''),
              (n = s),
              (i += f),
              (f = 0));
      },
      _pushTextBgRect: function(t, e, i, r, n, s) {
        var o = fabric.Object.NUM_FRACTION_DIGITS;
        t.push(
          '\t\t<rect ',
          this._getFillAttributes(e),
          ' x="',
          l(i, o),
          '" y="',
          l(r, o),
          '" width="',
          l(n, o),
          '" height="',
          l(s, o),
          '"></rect>\n'
        );
      },
      _setSVGTextLineBg: function(t, e, i, r) {
        for (
          var n,
            s,
            o = this._textLines[e],
            a = this.getHeightOfLine(e) / this.lineHeight,
            h = 0,
            c = 0,
            l = this.getValueOfPropertyAt(e, 0, 'textBackgroundColor'),
            u = 0,
            f = o.length;
          u < f;
          u++
        )
          (n = this.__charBounds[e][u]),
            (s = this.getValueOfPropertyAt(e, u, 'textBackgroundColor')) !== l
              ? (l && this._pushTextBgRect(t, l, i + c, r, h, a),
                (c = n.left),
                (h = n.width),
                (l = s))
              : (h += n.kernedWidth);
        s && this._pushTextBgRect(t, s, i + c, r, h, a);
      },
      _getFillAttributes: function(t) {
        var e = t && 'string' == typeof t ? new fabric.Color(t) : '';
        return e && e.getSource() && 1 !== e.getAlpha()
          ? 'opacity="' +
              e.getAlpha() +
              '" fill="' +
              e.setAlpha(1).toRgb() +
              '"'
          : 'fill="' + t + '"';
      },
      _getSVGLineTopOffset: function(t) {
        for (var e, i = 0, r = 0; r < t; r++) i += this.getHeightOfLine(r);
        return (
          (e = this.getHeightOfLine(r)),
          {
            lineTop: i,
            offset:
              ((this._fontSizeMult - this._fontSizeFraction) * e) /
              (this.lineHeight * this._fontSizeMult),
          }
        );
      },
      getSvgStyles: function(t) {
        return (
          fabric.Object.prototype.getSvgStyles.call(this, t) +
          ' white-space: pre;'
        );
      },
    });
  })(),
  (function(t) {
    'use strict';
    var v = t.fabric || (t.fabric = {});
    (v.Textbox = v.util.createClass(v.IText, v.Observable, {
      type: 'textbox',
      minWidth: 20,
      dynamicMinWidth: 2,
      __cachedLines: null,
      lockScalingFlip: !0,
      noScaleCache: !1,
      _dimensionAffectingProps: v.Text.prototype._dimensionAffectingProps.concat(
        'width'
      ),
      initDimensions: function() {
        this.__skipDimension ||
          (this.isEditing && this.initDelayedCursor(),
          this.clearContextTop(),
          this._clearCache(),
          (this.dynamicMinWidth = 0),
          (this._styleMap = this._generateStyleMap(this._splitText())),
          this.dynamicMinWidth > this.width &&
            this._set('width', this.dynamicMinWidth),
          -1 !== this.textAlign.indexOf('justify') && this.enlargeSpaces(),
          (this.height = this.calcTextHeight()),
          this.saveState({ propertySet: '_dimensionAffectingProps' }));
      },
      _generateStyleMap: function(t) {
        for (
          var e = 0, i = 0, r = 0, n = {}, s = 0;
          s < t.graphemeLines.length;
          s++
        )
          '\n' === t.graphemeText[r] && 0 < s
            ? ((i = 0), r++, e++)
            : this._reSpaceAndTab.test(t.graphemeText[r]) &&
              0 < s &&
              (i++, r++),
            (n[s] = { line: e, offset: i }),
            (r += t.graphemeLines[s].length),
            (i += t.graphemeLines[s].length);
        return n;
      },
      styleHas: function(t, e) {
        if (this._styleMap && !this.isWrapping) {
          var i = this._styleMap[e];
          i && (e = i.line);
        }
        return v.Text.prototype.styleHas.call(this, t, e);
      },
      isEmptyStyles: function(t) {
        var e,
          i,
          r = 0,
          n = !1,
          s = this._styleMap[t],
          o = this._styleMap[t + 1];
        for (var a in (s && ((t = s.line), (r = s.offset)),
        o && ((n = o.line === t), (e = o.offset)),
        (i = void 0 === t ? this.styles : { line: this.styles[t] })))
          for (var h in i[a])
            if (r <= h && (!n || h < e)) for (var c in i[a][h]) return !1;
        return !0;
      },
      _getStyleDeclaration: function(t, e) {
        if (this._styleMap && !this.isWrapping) {
          var i = this._styleMap[t];
          if (!i) return null;
          (t = i.line), (e = i.offset + e);
        }
        return this.callSuper('_getStyleDeclaration', t, e);
      },
      _setStyleDeclaration: function(t, e, i) {
        var r = this._styleMap[t];
        (t = r.line), (e = r.offset + e), (this.styles[t][e] = i);
      },
      _deleteStyleDeclaration: function(t, e) {
        var i = this._styleMap[t];
        (t = i.line), (e = i.offset + e), delete this.styles[t][e];
      },
      _getLineStyle: function(t) {
        var e = this._styleMap[t];
        return this.styles[e.line];
      },
      _setLineStyle: function(t, e) {
        var i = this._styleMap[t];
        this.styles[i.line] = e;
      },
      _deleteLineStyle: function(t) {
        var e = this._styleMap[t];
        delete this.styles[e.line];
      },
      _wrapText: function(t, e) {
        var i,
          r = [];
        for (this.isWrapping = !0, i = 0; i < t.length; i++)
          r = r.concat(this._wrapLine(t[i], i, e));
        return (this.isWrapping = !1), r;
      },
      _measureWord: function(t, e, i) {
        var r,
          n = 0;
        i = i || 0;
        for (var s = 0, o = t.length; s < o; s++) {
          (n += this._getGraphemeBox(t[s], e, s + i, r, !0).kernedWidth),
            (r = t[s]);
        }
        return n;
      },
      _wrapLine: function(t, e, i, r) {
        var n = 0,
          s = [],
          o = [],
          a = t.split(this._reSpaceAndTab),
          h = '',
          c = 0,
          l = 0,
          u = 0,
          f = 0,
          d = !0,
          g = this._getWidthOfCharSpacing();
        i -= r = r || 0;
        for (var p = 0; p < a.length; p++)
          (h = v.util.string.graphemeSplit(a[p])),
            (l = this._measureWord(h, e, c)),
            (c += h.length),
            i <= (n += u + l - g) && !d
              ? (s.push(o), (o = []), (n = l), (d = !0))
              : (n += g),
            d || o.push(' '),
            (o = o.concat(h)),
            (u = this._measureWord([' '], e, c)),
            c++,
            (d = !1),
            f < l && (f = l);
        return (
          p && s.push(o),
          f + r > this.dynamicMinWidth && (this.dynamicMinWidth = f - g + r),
          s
        );
      },
      isEndOfWrapping: function(t) {
        return (
          !this._styleMap[t + 1] ||
          this._styleMap[t + 1].line !== this._styleMap[t].line
        );
      },
      _splitTextIntoLines: function(t) {
        for (
          var e = v.Text.prototype._splitTextIntoLines.call(this, t),
            i = this._wrapText(e.lines, this.width),
            r = new Array(i.length),
            n = 0;
          n < i.length;
          n++
        )
          r[n] = i[n].join('');
        return (e.lines = r), (e.graphemeLines = i), e;
      },
      getMinWidth: function() {
        return Math.max(this.minWidth, this.dynamicMinWidth);
      },
      toObject: function(t) {
        return this.callSuper('toObject', ['minWidth'].concat(t));
      },
    })),
      (v.Textbox.fromObject = function(t, e) {
        return v.Object._fromObject('Textbox', t, e, 'text');
      });
  })('undefined' != typeof exports ? exports : this),
  (function() {
    var l = fabric.Canvas.prototype._setObjectScale;
    (fabric.Canvas.prototype._setObjectScale = function(t, e, i, r, n, s, o) {
      var a = e.target;
      if (!('x' === n && a instanceof fabric.Textbox))
        return l.call(fabric.Canvas.prototype, t, e, i, r, n, s, o);
      var h = a._getTransformedDimensions().x,
        c = a.width * (t.x / h);
      return c >= a.getMinWidth() ? (a.set('width', c), !0) : void 0;
    }),
      fabric.util.object.extend(fabric.Textbox.prototype, {
        _removeExtraneousStyles: function() {
          for (var t in this._styleMap)
            this._textLines[t] || delete this.styles[this._styleMap[t].line];
        },
      });
  })();
